Kan ik meerdere primaire sleutels in één tabel hebben?

Kan ik meerdere primaire sleutels in één tabel hebben?


Antwoord 1, autoriteit 100%

Een tabel kan een Samengestelde primaire sleutelhebben. Dit is een primaire sleutel die uit twee of meer kolommen bestaat. Bijvoorbeeld:

CREATE TABLE userdata (
  userid INT,
  userdataid INT,
  info char(200),
  primary key (userid, userdataid)
);

Update:Hier is een linkmet een meer gedetailleerde beschrijving van samengestelde primaire sleutels.


Antwoord 2, autoriteit 35%

U kunt slechts één primaire sleutel hebben, maar u kunt meerdere kolommen in uw primaire sleutel hebben.

U kunt ook unieke indexen in uw tabel hebben, die een beetje werken als een primaire sleutel omdat ze unieke waarden afdwingen en het opvragen van die waarden versnellen.


Antwoord 3, autoriteit 7%

Een tabel kan meerdere kandidaatsleutels hebben. Elke kandidaatsleutel is een kolom of reeks kolommen die UNIEK zijn, samen genomen, en ook NIET NULL. Het opgeven van waarden voor alle kolommen van een kandidaatsleutel is dus voldoende om te bepalen of er één rij is die aan de criteria voldoet, of helemaal geen rijen.

Kandidaatsleutels zijn een fundamenteel concept in het relationele datamodel.

Als er meerdere sleutels in één tabel aanwezig zijn, is het gebruikelijk om een van de kandidaatsleutels als primaire sleutel aan te wijzen. Het is ook gebruikelijk om externe sleutels naar de tabel te laten verwijzen naar de primaire sleutel in plaats van naar een andere kandidaatsleutel.

Ik raad deze werkwijzen aan, maar er is niets in het relationele model dat vereist dat een primaire sleutel uit de kandidaatsleutels moet worden geselecteerd.


Antwoord 4, autoriteit 3%

Dit is het antwoord op zowel de hoofdvraag als op @Kalmi’s vraag

Wat heeft het voor zin om meerdere automatisch genererende kolommen te hebben?

Deze code hieronder heeft een samengestelde primaire sleutel. Een van de kolommen wordt automatisch verhoogd. Dit werkt alleen in MyISAM. InnoDB zal een fout genereren “ERROR 1075 (42000): Incorrecte tabeldefinitie; er kan maar één autokolom zijn en deze moet worden gedefinieerd als een sleutel“.

DROP TABLE IF EXISTS `test`.`animals`;
CREATE TABLE  `test`.`animals` (
  `grp` char(30) NOT NULL,
  `id` mediumint(9) NOT NULL AUTO_INCREMENT,
  `name` char(30) NOT NULL,
  PRIMARY KEY (`grp`,`id`)
) ENGINE=MyISAM;
INSERT INTO animals (grp,name) VALUES
    ('mammal','dog'),('mammal','cat'),
    ('bird','penguin'),('fish','lax'),('mammal','whale'),
    ('bird','ostrich');
SELECT * FROM animals ORDER BY grp,id;
Which returns:
+--------+----+---------+
| grp    | id | name    |
+--------+----+---------+
| fish   |  1 | lax     |
| mammal |  1 | dog     |
| mammal |  2 | cat     |
| mammal |  3 | whale   |
| bird   |  1 | penguin |
| bird   |  2 | ostrich |
+--------+----+---------+

Antwoord 5, autoriteit 2%

(Heb deze veel bestudeerd)

Kandidaatsleutels– Een minimale kolomcombinatie die vereist is om een tabelrij uniek te identificeren.
Samengestelde toetsen– 2 of meer kolommen.

  • Meerdere Kandidaatsleutelskunnen in een tabel voorkomen.
    • Primaire SLEUTEL– Slechts één van de kandidaatsleutels die door ons gekozenis
    • Alternatieve sleutels– Alle anderekandidaatsleutels
      • Zowel primaire sleutel als Alternatieve sleutels kunnen Samengestelde sleutels
      • zijn

Bronnen:
https://en.wikipedia.org/wiki/supertoets
https://en.wikipedia.org/wiki/candidate_key
https://en.wikipedia.org/wiki/primary_key
https://en.wikipedia.org/wiki/compound_key


6

Primaire sleutel is erg ongelukkige notatie, vanwege de connotatie van “primaire” en de onderbewuste associatie bijgevolg met het logische model. Ik vermijd het dus met het gebruik ervan. In plaats daarvan verwijs ik naar de surrogaattoets van het fysieke model en de natuurlijke sleutel (s) van het logische model.

Het is belangrijk dat het logische model voor elke entiteit ten minste één set “bedrijfskenmerken” heeft die een sleutel voor de entiteit omvatten. Boyce, Codd, Datum et al Zie deze in het relationele model als kandidaat-sleutels. Wanneer we vervolgens tabellen voor deze entiteiten bouwen, worden hun kandidaat-toetsen in de natuurlijke toetsen in die tafels. Het is alleen door die natuurlijke sleutels die gebruikers in staat zijn om rijen in de tafels uniek te identificeren; Zoals de surrogaattoetsen altijd van gebruikers moeten worden verborgen. Dit komt omdat surrogaattoetsen geen bedrijfsbetekenis hebben.

Maar het fysieke model voor onze tabellen zal in veel gevallen inefficiënt zijn zonder een surrogaatsleutel. Bedenk dat niet-bedekte kolommen voor een niet-geclusterde index alleen (in het algemeen) kunnen worden gevonden via een sleutelzoeking in de geclusterde index (negeer tabellen die even worden geïmplementeerd als een moment). Wanneer onze beschikbare natuurlijke sleutel (en) breed zijn, verbreedt dit (1) de breedte van onze niet-geclusterde bladknooppunten, toenemende opslagvereisten en lees toegangen voor zoektochten en scans van die niet-geclusterde index; en (2) vermindert fan-out van onze geclusterde index toenemende indexhoogte en indexgrootte, opnieuw toenemende lezings- en opslagvereisten voor onze geclusterde indexen; en (3) verhoogt de cache-eisen voor onze geclusterde indexen. Overschijnen van andere indexen en gegevens uit de cache.

Dit is waar een kleine surrogaatsleutel, die door het RDBMS wordt aangeduid als ‘de primaire sleutel’, nuttig is. Wanneer ingesteld als de clustersleutel, om te worden gebruikt voor sleutelzoekopdrachten in de geclusterde index vanuit niet-geclusterde indexen en externe sleutelzoekopdrachten uit gerelateerde tabellen, verdwijnen al deze nadelen. Onze geclusterde index-fan-outs nemen weer toe om de hoogte en grootte van de geclusterde index te verminderen, de cachebelasting voor onze geclusterde indexen te verminderen, het aantal leesbewerkingen te verminderen bij toegang tot gegevens via elk mechanisme (of het nu gaat om indexscan, index zoeken, niet-geclusterd opzoeken van sleutels of opzoeken van externe sleutels) en verminder de opslagvereisten voor zowel geclusterde als niet-geclusterde indexen van onze tabellen.

Houd er rekening mee dat deze voordelen alleen optreden als de surrogaatsleutel zowel klein als de clustersleutel is. Als een GUID als clustersleutel wordt gebruikt, zal de situatie vaak slechter zijn dan wanneer de kleinst beschikbare natuurlijke sleutel zou zijn gebruikt. Als de tabel is georganiseerd als een heap, wordt de 8-byte (heap) RowID gebruikt voor het opzoeken van sleutels, wat beter is dan een 16-byte GUID, maar minder performant dan een 4-byte integer.

Als een GUID moet worden gebruikt vanwege zakelijke beperkingen, is het de moeite waard om naar een betere clustersleutel te zoeken. Als bijvoorbeeld een kleine site-identifier en 4-byte “site-sequence-number” haalbaar is, kan dat ontwerp betere prestaties leveren dan een GUID als surrogaatsleutel.

Als de gevolgen van een heap (hash-join misschien) ervoor zorgen dat opslag de voorkeur heeft, moeten de kosten van een bredere clustersleutel worden afgewogen in de afwegingsanalyse.

Beschouw dit voorbeeld::

ALTER TABLE Persons
ADD CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName)

waar de tuple “(P_ID, LASTNAME) ” een unieke beperking vereist, en kan een langdurige Unicode-achternaam plus een 4-byte integer zijn, het zou wenselijk zijn om dit toe te kennen Constraint AS “Voeg constraint PK_PERSONID uniek niet-geclusterd (p_id, achternaam) ” en (2) afzonderlijk een kleine surrogaattoets, om de “primaire sleutel ” van een geclusterde index te zijn. Het is vermeldenswaard dat Anita mogelijk alleen de achternaam aan deze beperking wenst toe te voegen om dat een overdekt veld te maken, dat niet nodig is in een geclusterde index omdat alle velden eronder vallen.

De mogelijkheid in SQL Server om een ​​primaire sleutel aan te wijzen als niet-gecixeerd is een ongelukkige historische omstandigheid, vanwege een confcontatie van de betekenis “Preferred Natural of Candidate Key” (uit het logische model) met de betekenis “Lookup-sleutel in opslag” van het fysieke model. Mijn begrip is dat de oorspronkelijk Sybase SQL Server altijd een 4-byte ruiting heeft gebruikt, zowel in een hoop of een geclusterde index, als de “opzoeksleutel in opslag” van het fysieke model.


7

Sommige mensen gebruiken de term “primaire sleutel” om precies een geheel getal-kolom te betekenen die zijn waarden krijgt die zijn gegenereerd door een automatisch mechanisme. Bijvoorbeeld AUTO_INCREMENTin MySQL of IDENTITYin Microsoft SQL Server. Gebruik je de primaire sleutel in deze zin?

Zo ja, is het antwoord afhankelijk van het merk database dat u gebruikt. In MySQL kun je dit niet doen, krijg je een foutmelding:

mysql> create table foo (
  id int primary key auto_increment, 
  id2 int auto_increment
);
ERROR 1075 (42000): Incorrect table definition; 
there can be only one auto column and it must be defined as a key

In sommige andere merken database kunt u meer dan één automatisch genereren kolom in een tabel definiëren.


8

Een primaire sleutel is de sleutel die een record op unieke wijze identificeert en in alle indexen wordt gebruikt. Dit is waarom je er niet meer dan één kunt hebben. Het is over het algemeen ook de sleutel die wordt gebruikt bij het koppelen aan onderliggende tabellen, maar dit is geen vereiste. Het echte doel van een PK is ervoor te zorgen dat iets u in staat stelt een record op unieke wijze te identificeren, zodat gegevenswijzigingen van invloed zijn op het juiste record en zodat indexen kunnen worden gemaakt.

U kunt echter meerdere velden in één primaire sleutel plaatsen (een samengestelde PK). Dit maakt uw joins langzamer (vooral als het grotere velden van het tekenreekstype zijn) en uw indexen groter, maar het kan de noodzaak om joins uit te voeren in sommige van de onderliggende tabellen wegnemen. casus basis. Wanneer u dit doet, is elk veld zelf niet uniek, maar de combinatie ervan wel. Als een of meer van de velden in een samengestelde sleutel ook uniek moeten zijn, dan heb je er een unieke index op nodig. Het is echter waarschijnlijk dat als één veld uniek is, dit een betere kandidaat is voor de PK.

Nu heb je soms meer dan één kandidaat voor de PK. In dit geval kies je er een als de PK of gebruik je een surrogaatsleutel (ik geef persoonlijk de voorkeur aan surrogaatsleutels voor dit geval). En (dit is van cruciaal belang!) u voegt unieke indexen toe aan elk van de kandidaatsleutels die niet als PK zijn gekozen. Als de gegevens uniek moeten zijn, heeft deze een unieke index nodig, of het nu de PK is of niet. Dit is een probleem met de gegevensintegriteit. (Merk op dat dit ook het geval is wanneer u een surrogaatsleutel gebruikt; mensen krijgen problemen met surrogaatsleutels omdat ze vergeten unieke indexen op de kandidaatsleutels te maken.)

Er zijn soms momenten waarop u meer dan één surrogaatsleutel wilt (meestal de PK als u die heeft). In dit geval wil je niet meer PK’s, maar meer velden met automatisch gegenereerde sleutels. De meeste DB’s staan dit niet toe, maar er zijn manieren om dit te omzeilen. Overweeg eerst of het tweede veld kan worden berekend op basis van de eerste automatisch gegenereerde sleutel (Veld1 * -1 bijvoorbeeld) of misschien betekent de behoefte aan een tweede automatisch gegenereerde sleutel dat u een gerelateerde tabel moet maken. Gerelateerde tabellen kunnen een één-op-één relatie hebben. U zou dat afdwingen door de PK van de bovenliggende tabel toe te voegen aan de onderliggende tabel en vervolgens het nieuwe automatisch gegenereerde veld aan de tabel toe te voegen en vervolgens de velden die geschikt zijn voor deze tabel. Kies dan een van de twee sleutels als de PK en plaats een unieke index op de andere (het automatisch gegenereerde veld hoeft geen PK te zijn). En zorg ervoor dat u de FK toevoegt aan het veld in de bovenliggende tabel. Als u geen extra velden voor de onderliggende tabel heeft, moet u over het algemeen onderzoeken waarom u denkt dat u twee automatisch gegenereerde velden nodig heeft.


Antwoord 9

Het is niet mogelijk om twee primaire sleutels tegelijkertijd te hebben. Maar (ervan uitgaande dat je de case niet hebt verknoeid met de samengestelde sleutel), is het misschien wat je nodig hebt om één kenmerk uniek te maken.

CREATE t1(
c1 int NOT NULL,
c2 int NOT NULL UNIQUE,
...,
PRIMARY KEY (c1)
);

Merk echter op dat in relationele database een ‘Super-toets’ een subset van attributen is die een taple of rij in een tabel uniek identificeren. Een ‘sleutel’ is een ‘Super Key’ die een extra eigenschap heeft die een attribuut uit de sleutel verwijderen, maakt die sleutel niet meer een ‘Super-toets’ (of gewoon een ‘sleutel’ is een minimale supersleutel). Als er meer sleutels zijn, zijn ze allemaal kandidaat-toetsen. We selecteren een van de kandidaat-toetsen als een primaire sleutel. Dat is de reden waarom het praten over meerdere primaire sleutels voor een relatie of een tabel is een conflict.


10

Goede technische antwoorden werden op betere manier gegeven dan ik kan doen.
Ik kan alleen maar toevoegen aan dit onderwerp:

Als u iets wilt dat niet toegestaan ​​/ aanvaardbaar is, is het een goede reden om stap terug te nemen.

  1. Begrijp de kern van waarom het niet acceptabel is.
  2. Graaf meer in documentatie / tijdschriftartikelen / web en enz.
  3. Analyseren / herziening van het huidige ontwerp en punt Major Foura’s.
  4. Overweeg en test elke stap tijdens het nieuwe ontwerp.
  5. kijk altijd naar voren en probeer een adaptieve oplossing te maken.

Ik hoop dat het iemand zal helpen.


11

Ja, het is mogelijk in SQL,
Maar we kunnen niet meer dan één primaire sleutels in MSACCESS instellen.
Dan weet ik niet over de andere databases.

CREATE TABLE CHAPTER (
    BOOK_ISBN VARCHAR(50) NOT NULL,
    IDX INT NOT NULL,
    TITLE VARCHAR(100) NOT NULL,
    NUM_OF_PAGES INT,
    PRIMARY KEY (BOOK_ISBN, IDX)
);

Other episodes