sql >> Database >  >> RDS >> Mysql

Fout 1005 in MySQL (van externe sleutelsyntaxis?)

Uw fouten worden veroorzaakt door een onjuiste syntaxis van vreemde sleutels.

Ik denk echter dat u ID-velden moet gebruiken in plaats van samengestelde primaire sleutels te gebruiken . Er zijn een paar problemen met uw methode...

  • Het zal het voor de database moeilijker maken om tabellen samen te voegen in vergelijking met het gebruik van een integer (ID)-veld om samen te voegen (moeilijker ==meer verwerkingstijd).

  • Het is geldig om meerdere mensen met dezelfde naam te hebben, zelfs als u een middelste initiaal gebruikt.

  • Wat gebeurt er als je iemands naam moet veranderen? Ofwel omdat het verkeerd is opgeslagen of omdat ze zijn getrouwd of zo... Dat betekent dat je niet alleen je employee moet updaten tabel, maar de works table en elke andere tabel waarin je de naam als refererende sleutel hebt gebruikt.

Kijk hier eens naar:http://sqlfiddle.com/#! 2/2dc8c/3/0

Ik heb een tafel-ID aan elke tafel toegevoegd . Het is een unsigned int , wat betekent dat het niet negatief kan zijn (omdat dat niet logisch zou zijn). Het is ook auto_increment , wat betekent dat elke keer dat u een rij aan de tabel toevoegt, deze ID automatisch wordt gegenereerd en met 1 omhoog gaat.

    create table Employee (
          Employee_ID int unsigned auto_increment primary key,

          Lastname    varchar(10),
          FirstName   varchar(10),
          MidInitial  char(1),

          gender      char(1),

          street      varchar(10),
          city        varchar(10),

          unique (Lastname, FirstName, MidInitial)
      );

Je zou dingen als volgt aan deze tabel toevoegen:

    insert into Employee (Employee_ID, LastName, FirstName, MidInitial) 
                   values (null,       'Smith',  'John',    'K');

De null wordt de automatisch gegenereerde ID. Het zal uniek zijn voor elke rij.

Ook een unieke beperking betekent dat de combinatie van deze velden uniek moet zijn in de tabel. Met een bedrijf dat groot genoeg is, wed ik echter dat twee mensen dezelfde naam zullen hebben. In het echte leven zou ik willen voorstellen deze unieke beperking te verwijderen.

Ik heb soortgelijke wijzigingen aangebracht in de bedrijfstabel...

     create table company(
         company_ID      int unsigned auto_increment primary key,

         company_name    varchar(20),
         city            varchar(10),

         unique (company_name)
    );

Er kunnen dingen worden toegevoegd zoals:

     insert into company values (null, 'Taco Bell', 'Paris'); 

Dus... voor works .... in plaats van de volledige naam van elke persoon en de volledige bedrijfsnaam steeds opnieuw in deze tabel op te slaan, hoeven we nu alleen de ID's op te slaan.

    create table Works (
         works_id      int unsigned auto_increment primary key,

         employee_id   int unsigned, 
         compay_id     int unsigned,  

         salary        numeric(8,2), 

         foreign key (employee_id) references Employee (employee_id), 
         foreign key (compay_id) references company (company_id) 
    );

Je zou dingen kunnen toevoegen aan works zoals dit:

    insert into Works values (null, 1, 1, '10.00');

Aangezien John Smith onze eerste werknemer was, zou zijn Employee_ID 1 zijn. Om dat te verifiëren, probeert u select * from Employee where FirstName='John' and LastName='Smith' . Taco Bell zou ook company_id =1 krijgen. Door die waarden in te voegen in works , dat betekent dat John nu bij Taco Bell werkt.

Ik raad je ook aan velden toe te voegen zoals start_date en end_date en job_title naar je werktafel. En u zou ook speciale aandacht willen besteden aan eventuele unieke beperkingen voor deze tafel. Mensen kunnen meerdere keren voor hetzelfde bedrijf werken. Ze kunnen ook verschillende banen hebben.

Als u uw gegevens weer wilt ophalen, gebruikt u een zoekopdracht als deze:

  select FirstName, MidInitial, LastName, 
         Company_Name, 
         Salary 

  from   employee

         join works 
           on works.employee_id = employee.employee_id

         join company 
           on works.company_id = company.company_id 

wat gewoon een mooie manier is om dit te zeggen:

  select FirstName, MidInitial, LastName, 
         Company_Name, 
         Salary 

  from   employee, works, company

  where  employee.employee_id = works.employee_id and

         company.company_id = works.company_id  

Enkele opmerkingen over database-dingen...

  • Kies een naamgevingsconventie en houd je eraan! Als je CamelCase wilt gebruiken , gebruik het overal. Als you_want_to_use onderstrepingstekens in uw namen, gebruik ze overal. Er zijn talloze naamgevingsconventies om uit te kiezen:attributen (kolommen/velden) voorafgaan aan de tabelnaam, algemene afkortingen gebruiken (of niet), waar hoofdletters worden gebruikt (of niet) ... dit komt meestal neer op persoonlijke voorkeur, maar er is zijn artikelen die er zijn over de voor- en nadelen van het gebruik van bepaalde. Laatste opmerking, _alleen omdat je spaties in een naam kunt gebruiken,__ betekent niet dat je dat zou moeten doen. `Almost all` databases laten [you use spaces] in namen als je wilt, maar het kan later veel problemen veroorzaken.

  • Tabelnamen mogen geen meervoud zijn. Dit is een stokpaardje van mij en dit is waarom:we weten dat een tafel veel records zal bevatten... veel mensen/personen, veel werknemers, meerdere bedrijven, meerdere vermeldingen van welk type of soort dan ook. Elke rij beschrijft slechts één van deze dingen. Soms heeft het gewoon geen zin om de naam in het meervoud te hebben. Andere keren is het twijfelachtig - zoals de works tafel. Als je het soms meervoud en soms enkelvoud maakt, kan het later verwarrend worden. Door het allemaal enkelvoud te maken, is het nog steeds volkomen logisch, en je hoeft niet heen en weer te schakelen of de exacte naam op te zoeken bij het schrijven van vragen.

  • Gegevenstypen zijn belangrijk en probeer consistent te zijn in alle tabellen voor vergelijkbare velden (zoals alle id is van hetzelfde type; maak alle booleaanse velden allemaal bits of gehele getallen of wat dan ook, maak ze gewoon hetzelfde). Er zijn verschillende groottes van integer-types waaruit u kunt kiezen. Denk na over grootte, prestaties en wat geschikt is voor uw behoeften. Bepaal of je echt een nvarchar nodig hebt of dat een varchar in orde is.

    • Data mogen nooit worden opgeslagen als een string. Gebruik het juiste datatype voor datum, datum/tijd, tijd of tijdstempel . Dit zal u later zoveel helpen wanneer u het moet ophalen, vergelijken of gebruiken in berekeningen. Een andere belangrijke beslissing is hoe u ervoor kiest om met tijdzones om te gaan . Ik vind het leuk om alles in UTC op te slaan en alle tijdzone-offset-dingen aan de voorkant af te handelen, wanneer de informatie aan de gebruiker wordt gepresenteerd. Dit houdt alles consistent en ik hoef me geen zorgen te maken of de rij om 18.00 uur is ingevoegd op basis van de computertijd van mijn gebruiker, de browsertijd van de gebruiker, de tijd van mijn database of de tijd van de server.

  • Voeg een ID toe veld dat is uniek voor de rij in elke tabel. De eenvoudigste manier om dit te doen, is door een auto_increment . te gebruiken (mysql) of identity(1,1) (sql server) veld zodat de database het voor je bijhoudt. Deze waarden kunnen worden gereset of opnieuw worden geplaatst als u ze nodig hebt.

  • Leer om normalisatie te gebruiken .

  • Ontdek welke transacties doen en waarom ze belangrijk zijn... zelfs als u ze niet gebruikt.

  • Meer informatie over de verschillende soorten joins . Dit is een van de beste verklaringen die ik ooit heb gezien. Het belangrijkste om op te letten is of de join een outer of inner join moet zijn.

  • Meer informatie over SQL-injectie en nog belangrijker, hoe om het te voorkomen (die link is voor PHP).

  • Als je PHP gebruikt, gebruik dan niet de oude mysql_ klas. Gebruik in plaats daarvan PDO of MySQLi_ . Info...

  • Het grote ding over databases is gegevensintegriteit, validatie en opschoning . Gebruikers zullen allerlei slordige, vuile gegevens in uw tabellen willen plaatsen. Is het MO of Missouri? Vrouw, V, vrouw, meisje of ja? Is het salaris 15,00 per uur, 50k per jaar of 3.000 een salaris? Is het 31-12-2013, 31-12-2013, 31-12-13, 31 december 2013 of vijfendertig december tweeduizend dertien?

  • Beslis of je NULL wilt toestaan of niet. Het maakt de zaken ingewikkelder vanwege de drievoudige toestandslogica en u zult het later moeten controleren. Sommige mensen besluiten om in plaats daarvan gewoon een lege string te gebruiken. NULL is meer een toestand dan een werkelijke waarde en het betekent ongedefinieerd of onbekend - de waarde kan van alles zijn. Ik gebruik null omdat een lege string soms een geldige waarde is voor een veld. Bijvoorbeeld het instellen van Middle_Initial gelijk zijn aan een lege tekenreeks kan betekenen dat de persoon geen middelste initiaal heeft of dat u gewoon niet weet wat het is. Voor mij zijn deze dingen anders. Voor andere mensen maakt het verschil niet uit. Denk maar aan getallen... is 0 hetzelfde als onbekend?

  • Als er niets anders is, wees dan gewoon consistent.



  1. Kan geen MySQL-trigger maken met TRIGGER-privilege op 5.1.32

  2. Zijn PostgreSQL-kolomnamen hoofdlettergevoelig?

  3. Externe sleutelcontroles op de opdrachtregel uitschakelen

  4. Django:aangepaste onbewerkte SQL-inserts gebruiken met executemany en MySQL