[database] IDs
Ik twijfel over een paar dingen, en voordat ik verder ga met m'n database wil ik graag weten wat volgens jullie de handigste aanpak is. Ik zal even een paar fictieve scenario's schetsen (genummerd) en kunnen jullie dan per nummer zeggen wat volgens jullie de beste optie is?
Scenario 1:
Een tabel met producten. Ieder product heeft een unieke productcode die bestaat uit alfanumerieke tekens (cijfers, letters, underscores). Wat is de juiste optie:
optie 1, id is PK:
optie 2, productcode is PK (het veld id vervalt):
Wat is volgens jullie de beste/handigste optie? Anders gezegd: welke optie zouden jullie kiezen?
Scenario 2:
Een tabel met "bezorg statussen" die een unieke waarde hebben, denk aan "onderweg", "verzonden", "afgeleverd".
optie 1, id is PK:
optie 2, status is PK (de tabel bestaat maar uit 1 kolom, er is geen id):
Wat is volgens jullie de beste/handigste optie?
Scenario 3:
Een tabel met teksten. Iedere tekst heeft een eigen ID die ik in PHP kan oproepen via echo $tekst->get($id). Bijvoorbeeld de tekst "Welkom op deze website waar u van alles kunt lezen over PHP." heeft als ID "welkom". In PHP: echo $tekst->get('welkom');
optie 1, id is PK:
Bij optie 2 wordt het vreemd, want stel dat ik een numeriek ID wil, dan heb ik dus 2 IDs. Eén van beide IDs zou dan een andere naam moeten krijgen wat eigenlijk niet wenselijk is. Tips?
optie 2, db_id is PK:
optie 3, id is PK:
Wat is volgens jullie de beste/handigste optie?
Ik hoop dat jullie me een beetje kunnen helpen om inzicht te krijgen hoe ik het beste mijn IDs inregel.
Gewijzigd op 10/05/2013 14:03:02 door Ozzie PHP
Gewoon niet zo moeilijk doen en altijd een id geven.
Want wat doe je dan als je bijv. personen invoert en iedere persoon heeft een uniek BSN nummer? Voeg jij dan toch een (auto increment) ID toe en stel je die in als primary key? Of laat je het ID achterwege en wordt het BSN nummer de primary key?
Graag je reactie.
Dit omdat met ID's tabellen makkelijk aan elkaar te koppelen zijn. Ook als jij een grote database hebt kun je data sneller iets uit meerdere tabellen halen doormiddel van een ID. Dit omdat het heel simpel weinig karakters heeft.
Als je wil weten hoe je het beste je database kunt opbouwen kun je denk ik het best even zoeken op databasenormalisatie.
Gewijzigd op 10/05/2013 14:10:41 door Rick van Riel
2 - Sowieso is status geen PK, het is namelijk niet uniek voor elke rij. Sterker nog, de statussen krijgen een aparte tabel en je krijgt weer 2x PK (package.id, status.id) en 1x FK (package.status_id)
3.2 - met de kolommen index, id, text (of liever: id, source, target)
Gewijzigd op 10/05/2013 14:15:16 door Wouter J
Ander voorbeeld... stel op mijn site kan iemand een product zoeken op basis van het productnummer. Dan zullen mensen het productnummer intypen en niet het ID in de database. En volgens mij is een ID nu juist datgene waarnaar gezocht moet worden in de database.
Graag zou ik hier dus iets meer duidelijkheid over willen hebben.
Of is de "regel": gebruik altijd een auto-increment ID?
Toevoeging op 10/05/2013 14:15:26:
Momentje Wouter... ik ga even reageren op jouw opmerkingen...
De PK moet naar mijn mening aan 2 voorwaarden voldoen: (a) uniek per rij en (b) het veld die het meest gebruikt wordt om teksten op te halen
Wouter J op 10/05/2013 14:14:04:
1.2 - Primary key is niet perse het ID. Een PK is uniek, dus een product code ook
2 - Sowieso is status geen PK, het is namelijk niet uniek voor elke rij. Sterker nog, de statussen krijgen een aparte tabel en je krijgt weer 2x PK (package.id, status.id) en 1x FK (package.status_id)
3.2 - met de kolommen index, id, text (of liever: id, source, target)
2 - Sowieso is status geen PK, het is namelijk niet uniek voor elke rij. Sterker nog, de statussen krijgen een aparte tabel en je krijgt weer 2x PK (package.id, status.id) en 1x FK (package.status_id)
3.2 - met de kolommen index, id, text (of liever: id, source, target)
Ad 1.2: maar een auto-increment ID wordt toch automatisch de PK? Hoe zou jij het dan doen? De productcode als PK en geen ID? Of begrijp ik je verkeerd?
Ad 2: ik bedoel hier de tabel waar de verschillende mogelijke statussen in zijn opgeslagen. In dat geval is status dus wel uniek (we bedoelen waarschijnlijk hetzelfde).
Ad 3.2: source en target? Oké, dat zou kunnen, maar dan wijk je wel af van ID-value, maar goed dat is een keuze.
Toevoeging op 10/05/2013 14:22:31:
Wouter J op 10/05/2013 14:18:24:
De PK moet naar mijn mening aan 2 voorwaarden voldoen: (a) uniek per rij en (b) het veld die het meest gebruikt wordt om teksten op te halen
Mee eens. In het geval van de teksten zou dat betekenen dat ID ("welkom") dus de PK zou zijn. Maar wat heeft een numerieke ID ("index" zoals jij het zou noemen) dan nog voor waarde?
2: dan een ID
3: dat is de naam die wordt gebruikt in de XLIFF standaard, het meest gebruikte formaat voor i18n.
Gewijzigd op 10/05/2013 14:25:47 door Wouter J
Ozzie PHP op 10/05/2013 14:08:11:
Want wat doe je dan als je bijv. personen invoert en iedere persoon heeft een uniek BSN nummer? Voeg jij dan toch een (auto increment) ID toe en stel je die in als primary key?
Ja
Ozzie PHP op 10/05/2013 14:08:11:
Of laat je het ID achterwege en wordt het BSN nummer de primary key?
Nee
Deze wordt wel uiteraard unique
Gewijzigd op 10/05/2013 14:28:51 door - SanThe -
Ozzie PHP op 10/05/2013 14:20:22:
Mee eens. In het geval van de teksten zou dat betekenen dat ID ("welkom") dus de PK zou zijn. Maar wat heeft een numerieke ID ("index" zoals jij het zou noemen) dan nog voor waarde?
Je hoeft natuurlijk geen numerieke PK te gebruiken als je dat zelf niet wil maar zoals ik eerder al aangeven. Maar het gebruik ervan is wel veel sneller er word in alle normalisatie methodes gebruikt. Hij is dus eigenlijk een ongeschreven regel. Als jij denk dat "welkom" de PK moet zijn omdat je weet dat dit altijd een unieke waarde zal zijn kun je het als het waren gewoon gebruiken, maar ik raad het dus niet aan.
1) Oké, jij zou hier dus weer geen ID gebruiken, maar hierboven (Santhe) wordt weer gezegd dat je ALTIJD een ID moet gebruiken. Snap je de verwarring?
2) oké
3) Oehh, je slaat me weer om de oren met een paar indrukwekkende afkortingen :) Maar in dat geval... is het dan beter om de term "index" te gebruiken waar ik normaal geneigd zou zijn om "ID" te gebruiken?
Toevoeging op 10/05/2013 14:29:39:
Crap... wat gaat het ineens snel.. Santhe en Rick... momentje dan reageer ik op jullie...
2. prima!
3. ik zou altijd ID gebruiken en alleen index wanneer id al bezet is. (en i18n staat voor internationalization (tussen de i en n zitten 18 tekens), oftewel translation)
- SanThe - op 10/05/2013 14:27:55:
Ja
Nee
Deze wordt wel uiteraard unique
Ozzie PHP op 10/05/2013 14:08:11:
Want wat doe je dan als je bijv. personen invoert en iedere persoon heeft een uniek BSN nummer? Voeg jij dan toch een (auto increment) ID toe en stel je die in als primary key?
Ja
Ozzie PHP op 10/05/2013 14:08:11:
Of laat je het ID achterwege en wordt het BSN nummer de primary key?
Nee
Deze wordt wel uiteraard unique
Oké... maar waarom doe je dat op deze manier? Welke gedachte zit daarachter? Zodat je de persoon via de ID (in plaats van BSN) ergens aan kunt koppelen?
Rick van Riel op 10/05/2013 14:28:36:
Je hoeft natuurlijk geen numerieke PK te gebruiken als je dat zelf niet wil maar zoals ik eerder al aangeven. Maar het gebruik ervan is wel veel sneller er word in alle normalisatie methodes gebruikt. Hij is dus eigenlijk een ongeschreven regel. Als jij denk dat "welkom" de PK moet zijn omdat je weet dat dit altijd een unieke waarde zal zijn kun je het als het waren gewoon gebruiken, maar ik raad het dus niet aan.
Ozzie PHP op 10/05/2013 14:20:22:
Mee eens. In het geval van de teksten zou dat betekenen dat ID ("welkom") dus de PK zou zijn. Maar wat heeft een numerieke ID ("index" zoals jij het zou noemen) dan nog voor waarde?
Je hoeft natuurlijk geen numerieke PK te gebruiken als je dat zelf niet wil maar zoals ik eerder al aangeven. Maar het gebruik ervan is wel veel sneller er word in alle normalisatie methodes gebruikt. Hij is dus eigenlijk een ongeschreven regel. Als jij denk dat "welkom" de PK moet zijn omdat je weet dat dit altijd een unieke waarde zal zijn kun je het als het waren gewoon gebruiken, maar ik raad het dus niet aan.
Ik snap je gedachtengang, maar in mijn code zal ik echo getText('welkom'); moeten gebruiken en niet bijv. echo getText(56); Snap je? Dus wat is op dat moment de meerwarde dan van een ID?
Toevoeging op 10/05/2013 14:36:21:
Wouter J op 10/05/2013 14:31:59:
1. Ja, het is dus weer zoals altijd: Beslis wat jij wilt
2. prima!
3. ik zou altijd ID gebruiken en alleen index wanneer id al bezet is. (en i18n staat voor internationalization (tussen de i en n zitten 18 tekens), oftewel translation)
2. prima!
3. ik zou altijd ID gebruiken en alleen index wanneer id al bezet is. (en i18n staat voor internationalization (tussen de i en n zitten 18 tekens), oftewel translation)
1. Hehe, het blijft toch ook lachen he dat programmeren ;)
2. yes! :)
3. ik heb ze geteld... het klopt! haha...
Maar goed... blijkbaar is het toch best lastig dat ID verhaal. Niet iedereen denkt er hetzelfde over zo te zien.
Ozzie PHP op 10/05/2013 14:33:35:
Ik snap je gedachtengang, maar in mijn code zal ik echo getText('welkom'); moeten gebruiken en niet bijv. echo getText(56); Snap je? Dus wat is op dat moment de meerwarde dan van een ID?
Als jij nu getText('welkom'); doet en je krijgt meerdere resultaten terug, dan heb je dus een probleem omdat je maar 1x welkom wil ophalen. Als je nou meerdere welkom teksten wil hebben dan moet je ze allemaal anders gaan noemen. Terwijl je met een ID meerdere rijen kunt hebben met de tekst "welkom" maar dan zijn ze wel allemaal uniek omdat ze dus allemaal een ander ID hebben.
Code (php)
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
<?php
$query = SELECT klant_id, klant_voornaam
FROM klant
WHERE klant_id = '1';
// doorloop je query execute etc
echo $var['klant_voornaam'];
?>
$query = SELECT klant_id, klant_voornaam
FROM klant
WHERE klant_id = '1';
// doorloop je query execute etc
echo $var['klant_voornaam'];
?>
zoals je ziet bepaal ik alleen dat ik op de ID moet zoeken maar het echoen kan ik met elk veld wat ik ophaal. dus stel dat jij de text ophaalt en de title en weet ik veel wat je nog meer wilt ophalen het gaat erom dat jij kan zeggen ik wil deze velden WAAR klant_id is gelijk aan 1
Toevoeging op 10/05/2013 14:50:49:
@Reshad: ik zie nu pas jouw opmerking...
Als ik nu een tabel heb met allerlei texten erin, dus iedere rij bevat een tekst, en ik wil daar 1 tekst uit selecteren... dan is dat toch een andere situatie dan die jij nu schetst?
Hoezo is dat een andere situatie?
Rick van Riel:
Je hoeft natuurlijk geen numerieke PK te gebruiken als je dat zelf niet wil maar zoals ik eerder al aangeven. Maar het gebruik ervan is wel veel sneller er word in alle normalisatie methodes gebruikt. Hij is dus eigenlijk een ongeschreven regel.
Normalisatie heeft het helemaal niet over hoe een PK eruit moet zien, alleen dat er een tabel er één moet hebben en dat ie uniek moet zijn en nooit NULL.
Neemt niet weg dat numerieke primary keys sneller zijn.
Ozzie, voordat je vraagt wat het scheelt:
Numeriek is minimaal 3x zo snel te indexeren.
Ik vind overigens niet dat je zomaar altijd een auto-increment kolom aan je tabel moet toevoegen, ik gebruik bv in een producten tabel gewoon de barcode als primary key.
@Reshad: de sitautie die jij schetst is anders. Jij haalt een klant op die als ID 1 heeft en vervolgens haal je de bijbehorende velden op. Als ik in PHP een text zou willen ophalen, dan weet ik niet wat het ID in de database is. Ik weet alleen dat ik de tekst moet ophalen op basis van het keywoord "welkom". Als ik dit doe: echo getText('welkom'); dan zou achter de schermen de query zou dus zoiets worden:
Snap je het verschil?
In beide gevallen zou ik een auto_increment kolom als primary key gebruiken.