MySQL: NULL, 0, vai -1 kā noklusētā vērtība?
Situācijas izklāsts: Divas tabulas: aģents un darbības. Tabulai darbības, laukam agentsID ir definēts foreign key uz tabulu aģents. Problēma: Nepieciešams izveidot noklusēto vērtību laukam agentsID.
Šoreiz tutoriāļa vietā būs pārdomas.
Situācijas izklāsts: Divas tabulas: aģents un darbības. Tabulai darbības, laukam agentsID ir definēts foreign key uz tabulu aģents.
Problēma: Nepieciešams izveidot noklusēto vērtību tai laukam agentsID.
Lai uzdevumu padarītu ne tik viennozīmīgu, pieņemsim, ka katrā tabulā ir 100’000 ierakstu un ka šie dati tiek izmantoti kādā programmā (piem. PHP). Līdz ar ko aktuāls kļūst jautājums par indeksēšanu un kārtošanu.
NULL kā noklusētā vērtība.
Pēc noklusējuma, izklāstītā situācijā tiek piedāvāts izmantot NULL. Šinī gadījumā veidojot jaunu ierakstu tabulā darbības, atslēga netiks meklēta tabulā aģents.
No vienas puses vērtība NULL ir „nekas” un varētu domāt, ka netiek indeksēta. Savukārt izpildot vaicājumu:
EXPLAIN SELECT * FROM darbības WHERE agentsID IS NULL
redzam, ka indeksi tomēr tiek izmantoti.
Nākošais apstāklis ir NULL vērtību apstrāde programmā (mūsu gadījumā PHP). Proti, atlasot NULL vērtības tās var rādīt kā tukšumu, kā tekstu „(null)” vai arī piešķirt kādu semantisko jēgu, piemēram, [aģents nav norādīts]. PHP gadījumā NULL tiks parādīts kā tukšā vērtība un labākajā gadījumā izsaucot Notice. Savukārt „skrupulozākās” valodās, piemēram , Java, tiks izsaukts exception.
Viss ir labi, līdz brīdim, kamēr šādi semantiskie NULL vērtības skaidrojumi jāsniedz vienā valodā.
0 kā noklusētā vērtība.
Šinī gadījumā, tā ir vērtība un tieši ar tādu atslēgu (key) jābūt ierakstam tabulā aģenti, lai to varētu izmantot arī tabulā darbības. Ieguvums – šādi varētu iegūt noklusēto ierakstu, līdz ar ko atrisinātos jautājums ko darīt ja default vērtībai jābūt dažādās valodās.
Ir arī problēma. Veidojot jaunu ierakstu, norādot id laukā vertību 0 (id lauks – int, auto_increment) automātiski stājas spēkā auto_increment nosacījums, resp. lauka vērtība vairs nepaliek 0, bet gan piešķirtā auto_increment vērtība.
Skaidrs ir viens, ka pie INSERT, pat ja izmantos id vērtību 0, ieraksts netiks izmainīts (jo tiks izveidots jauns ieraksts), savukārt backup/restore darbosies nekorekti, tā paša iemesla dēļ..
1 vai -1 kā noklusētā vērtība.
Trīs lietas labas lietas. Par noklusēto vērtību pieņemam pirmo ierakstu tabulā aģenti. Tātad 1. Savukārt ja id vērtība ir „signed”, tad iespējams izmantot arī -1;
-1 izskatās acij tīkamāk un turpmāk neradīs pārpratumus vizuāli aplūkojot datus. Gan 1, gan -1 ir vērtības līdz ar ko nav šaubu par indeksēšanas efektivitāti.
Zināms mulsums par negatīvo vērtību tomēr ir. Pirmkārt, nekad un nekur neesmu lasījis vai redzējis, ka par id vērtību izmantotu negatīvus skaitļus Otrkārt, bināri uzrakstot negatīvu skaitli vecākais bits (sign bit) mainās uz 1, iegūstot 1000....000010101. Un te nu es tā aizdomājos, kādu iespaidu tas varētu atstāt uz indeksēšanu pie vājprātīgi liela datu apjoma?
Lasāmviela par NULL:
- NULL, indeksi, surogātvērtības un citi zvēri
- MySQL lesson learned
Paldies, Ērik - jauka dāvana vārda dienā, svaigs raksts par MySQL (caprice).
Vienam meita, citam kleita :D
Sveiciens vārda dienā!
(oho)
Nu, es esmu redzējis, ka Oracle Warehouse Builder ģenerējot dimensijas izmanto negativus un pozitīvus ID, lai varētu atšķirt savas iekšējās lietas.