sql >> Databáze >  >> RDS >> Mysql

Chyba 1005 v MySQL (ze syntaxe cizího klíče?)

Vaše chyby jsou způsobeny nesprávnou syntaxí cizího klíče.

Myslím si však, že byste místo primárních klíčů složených z řetězců měli používat pole ID . S vaší metodou je několik problémů...

  • Ztíží to DB spojovat tabulky dohromady ve srovnání s použitím celočíselného (ID) pole ke spojování (těžší ==delší doba zpracování).

  • Platí, že má více lidí se stejným jménem, ​​a to i s použitím střední iniciály.

  • Co se stane, když budete muset někomu změnit jméno? Buď proto, že to bylo uloženo špatně, nebo se vzali nebo tak něco... To znamená, že budete muset nejen aktualizovat svého employee tabulka, ale works tabulka a jakákoli další tabulka, jejíž název jste použili jako cizí klíč.

Podívejte se na toto:http://sqlfiddle.com/#! 2/2dc8c/3/0

Do každé tabulky jsem přidal ID tabulky . Je to unsigned int , což znamená, že nemůže být negativní (protože by to nedávalo moc smysl). Je to také auto_increment , což znamená, že pokaždé, když do tabulky přidáte řádek, bude toto ID automaticky vygenerováno a zvýší se o 1.

    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)
      );

Do této tabulky byste přidali věci takto:

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

null se stane automaticky generovaným ID. Pro každý řádek bude jedinečný.

Také jedinečné omezení znamená, že kombinace těchto polí musí být v tabulce jedinečná. Nicméně s dostatečně velkou společností se vsadím, že dva lidé budou mít stejné jméno. V reálném životě bych doporučil toto jedinečné omezení odstranit.

Podobné změny jsem provedl v tabulce společnosti...

     create table company(
         company_ID      int unsigned auto_increment primary key,

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

         unique (company_name)
    );

Mohou být přidány věci jako:

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

Takže... pro works .... místo toho, abychom do této tabulky znovu a znovu ukládali celé jméno každé osoby a celý název společnosti, musíme nyní ukládat pouze ID.

    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) 
    );

Můžete přidat věci do works takto:

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

Vzhledem k tomu, že John Smith byl naším prvním zaměstnancem, jeho Employee_ID by bylo 1. Chcete-li to ověřit, zkuste select * from Employee where FirstName='John' and LastName='Smith' . Taco Bell by také získal company_id =1. Vložením těchto hodnot do works , to znamená, že John nyní pracuje v Taco Bell.

Také bych vám doporučil přidat pole jako start_date a end_date a job_title k vašemu pracovnímu stolu. A také byste chtěli věnovat zvláštní pozornost všem jedinečným omezením této tabulky. Lidé mohou pracovat pro stejnou společnost více než jednou. Mohou mít i různá zaměstnání.

Když chcete dostat svá data zpět, použijte dotaz jako tento:

  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 

což je jen skvělý způsob, jak to říct:

  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  

Několik poznámek k databázím...

  • Vyberte si konvenci pojmenování a držte se jí! Pokud chcete použít CamelCase , použijte to všude. Pokud you_want_to_use podtržítka ve svých jménech, používejte je všude. Existuje spousta konvencí pojmenování, ze kterých si můžete vybrat:předřazení atributů (sloupců/polí) názvu tabulky, používání běžných zkratek (nebo ne), kde se používá velká písmena (nebo ne)... to většinou závisí na osobních preferencích, ale existuje jsou tam články o výhodách a nevýhodách používání některých z nich. Poslední poznámka, _jen proto, že můžete ve jméně používat mezery,__ neznamená, že byste měli. `Almost all` databáze umožňují [you use spaces] v názvech, chcete-li, ale později to může způsobit spoustu problémů.

  • Názvy tabulek by neměly být množné. Toto je moje hnusná nálada a tady je důvod:Víme, že stůl pojme mnoho záznamů... mnoho lidí/osob, mnoho zaměstnanců, více společností, více položek jakéhokoli typu nebo druhu. Každý řádek popisuje pouze jeden z těchto věcí. Někdy prostě ani nedává smysl, aby jméno bylo v množném čísle. Jindy je to sporné - stejně jako works stůl. Pokud někdy uděláte množné číslo a někdy jednotné číslo, může to být později matoucí. Tím, že je to celé singulární, to stále dává dokonalý smysl a při psaní dotazů nemusíte přepínat tam a zpět ani nemusíte hledat přesný název.

  • Datové typy jsou důležité a pokuste se být konzistentní napříč tabulkami pro podobná pole (stejně jako všechny id s stejný typ; udělejte ze všech booleovských polí všechny bity nebo celá čísla nebo cokoli jiného, ​​prostě je udělejte stejně). Existují různé velikosti celočíselných typů, ze kterých si můžete vybrat. Zamyslete se nad velikostí, výkonem a tím, co je vhodné pro vaše potřeby. Rozhodněte se, zda opravdu potřebujete nvarchar nebo zda je varchar v pořádku.

    • Data by neměla nikdy být uložen jako řetězec. Použijte vhodný datový typ data, data a času, času nebo časového razítka . To vám později velmi pomůže, když jej budete potřebovat získat, porovnat nebo použít ve výpočtech. Dalším důležitým rozhodnutím je, jak jste se rozhodli nakládat s časovými pásmy . Rád ukládám vše v UTC a zpracovávám jakékoli offsety časového pásma na frontendu, když jsou informace prezentovány uživateli. Díky tomu je vše konzistentní a nemusím se starat o to, zda byl řádek vložen v 18:00 na základě času počítače mého uživatele, času prohlížeče uživatele, času mé databáze nebo času serveru.

  • Zahrňte ID pole který je jedinečný pro řádek v každé tabulce. Nejjednodušší způsob, jak toho dosáhnout, je použít auto_increment (mysql) nebo identity(1,1) (sql server), aby jej databáze sledovala za vás. Tyto hodnoty lze v případě potřeby resetovat nebo znovu nastavit.

  • Naučte se používat normalizaci .

  • Přečtěte si, jaké transakce dělat a proč jsou důležité... i když je nepoužíváte.

  • Přečtěte si o různých typech připojení . Toto je jedno z nejlepších vysvětlení Už jsem někdy viděl. Hlavní věc, kterou je třeba věnovat pozornost, je, zda by spojení mělo být vnější nebo vnitřní.

  • Další informace o SQL Injection a co je důležitější, jak abyste tomu zabránili (ten odkaz je pro PHP).

  • Pokud používáte PHP, nepoužívejte starý mysql_ třída. Místo toho použijte PDO nebo MySQLi_ . Informace...

  • Velká věc na databázích je integrita dat, ověřování a sanitace . Uživatelé budou chtít do vašich tabulek vkládat všechny druhy nedbalých a špinavých dat. Je to MO nebo Missouri? Žena, F, žena, dívka, nebo ano? Je mzda 15,00 za hodinu, 50 000 ročně nebo 3 000 výplata? Je to 31. 12. 2013, 31. 12. 2013, 31. 12. 13, 31. prosince 2013 nebo prosinec třicátých pěstí dva tisíce třináct?

  • Rozhodněte se, zda chcete povolit NULL nebo ne. Dělá to věci složitější kvůli logice trojitého stavu a budete to muset později zkontrolovat. Někteří lidé se rozhodnou místo toho použít prázdný řetězec. NULL je spíše stav než skutečná hodnota a znamená nedefinovaný nebo neznámý - hodnota může být jakákoli. Používám null protože prázdný řetězec je někdy platnou hodnotou pro pole. Například nastavení Middle_Initial rovnat se prázdnému řetězci může znamenat, že osoba nemá střední iniciálu, nebo to může znamenat, že prostě nevíte, co to je. Pro mě jsou tyto věci jiné. Pro ostatní lidi na rozdílu nezáleží. Stačí vzít v úvahu čísla... je 0 stejná jako neznámá?

  • Pokud nic jiného, ​​buďte důslední.



  1. Pokud se transakce PHP PDO nezdaří, musím explicitně rollback()?

  2. Nelze připojit PostgreSQL ke vzdálené databázi pomocí pgAdmin

  3. Proč není v QT5.2 načten ovladač QMYSQL?

  4. Proč SQLAlchemy spustit Aktualizace nefunguje