sql >> Base de Datos >  >> RDS >> Mysql

Error 1005 en MySQL (¿de sintaxis de clave externa?)

Sus errores se deben a una sintaxis de clave externa incorrecta.

Sin embargo, creo que debería usar campos de ID en lugar de hacer claves primarias compuestas de cadena . Hay algunos problemas con su método...

  • Será más difícil para la base de datos unir tablas en comparación con el uso de un campo de número entero (ID) para unirse (más difícil ==más tiempo de procesamiento).

  • Es válido tener varias personas con el mismo nombre, incluso usando una inicial del medio.

  • ¿Qué pasa si tienes que cambiar el nombre de alguien? Ya sea porque se almacenó mal o se casaron o algo... Eso significa que no solo tendrá que actualizar su employee tabla, pero el works tabla y cualquier otra tabla en la que haya usado el nombre como clave externa.

Mire esto:http://sqlfiddle.com/#! 2/2dc8c/3/0

He añadido un ID de tabla a cada tabla . Es un unsigned int , lo que significa que no puede ser negativo (porque eso no tendría mucho sentido). También es auto_increment , lo que significa que cada vez que agregue una fila a la tabla, esta ID se generará automáticamente y aumentará en 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)
      );

Agregarías cosas a esta tabla como esta:

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

El null se convertirá en el ID generado automáticamente. Será único para cada fila.

Además, una restricción única significa que la combinación de estos campos debe ser única en la tabla. Sin embargo, con una empresa lo suficientemente grande, apuesto a que dos personas tendrán el mismo nombre. En la vida real, sugeriría eliminar esta restricción única.

Hice cambios similares en la tabla de empresas...

     create table company(
         company_ID      int unsigned auto_increment primary key,

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

         unique (company_name)
    );

Se podrían agregar cosas como:

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

Entonces... para works .... en lugar de almacenar el nombre completo de cada persona y el nombre completo de la empresa una y otra vez en esta tabla, ahora solo tenemos que almacenar las identificaciones.

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

Podrías agregar cosas a works así:

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

Dado que John Smith fue nuestro primer empleado, su Employee_ID sería 1. Para verificar eso, intente select * from Employee where FirstName='John' and LastName='Smith' . Taco Bell también obtendría company_id =1. Al insertar esos valores en works , eso significa que John ahora trabaja en Taco Bell.

También te sugiero que agregues campos como start_date y end_date y job_title a tu mesa de trabajo. Y también querrá prestar especial atención a cualquier restricción única para esta tabla. Las personas pueden trabajar para la misma empresa más de una vez. También pueden tener diferentes trabajos.

Cuando desee recuperar sus datos, usaría una consulta como esta:

  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 

que es solo una forma elegante de decir esto:

  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  

Algunas notas sobre cosas de la base de datos...

  • ¡Elige una convención de nomenclatura y apégate a ella! Si quieres usar CamelCase , úsalo en todas partes. Si you_want_to_use guiones bajos en sus nombres, utilícelos en todas partes. Hay toneladas de convenciones de nomenclatura para elegir:prefijar atributos (columnas/campos) con el nombre de la tabla, usar abreviaturas comunes (o no), dónde se usan mayúsculas (o no)... esto se reduce principalmente a preferencias personales, pero hay hay artículos sobre los pros y los contras de usar ciertos. Última nota, _solo porque puede usar espacios en un nombre,__ no significa que deba hacerlo. `Almost all` las bases de datos permiten [you use spaces] en nombres si lo desea, pero puede causar muchos problemas más adelante.

  • Los nombres de las tablas no deben estar en plural. Este es uno de mis motivos favoritos y he aquí por qué:sabemos que una tabla tendrá muchos registros... muchas personas/personas, muchos empleados, múltiples empresas, múltiples entradas de cualquier tipo o tipo. Cada fila describe solo uno de estas cosas A veces ni siquiera tiene sentido tener el nombre en plural. Otras veces, es cuestionable, como el works mesa. Si a veces lo haces en plural y otras en singular, puede resultar confuso más adelante. Simplemente haciendo que todo sea singular, todavía tiene mucho sentido, y no está cambiando de un lado a otro o teniendo que buscar el nombre exacto al escribir consultas.

  • Los tipos de datos son importantes e intente ser coherente en todas las tablas para campos similares (como todos los id es del mismo tipo; haga que todos los campos booleanos sean bits o enteros o lo que sea, simplemente hágalos iguales). Hay diferentes tamaños de tipos de enteros entre los que puede elegir. Piense en el tamaño, el rendimiento y lo que es apropiado para sus necesidades. Decida si realmente necesita un nvarchar o si un varchar está bien.

    • Las fechas nunca almacenarse como una cadena. Utilice el tipo de datos de fecha, fecha y hora, hora o marca de tiempo adecuado . Esto te ayudará mucho más adelante cuando necesites recuperarlo, compararlo o usarlo en cálculos. Otra decisión importante es cómo elige manejar las zonas horarias . Me gusta almacenar todo en UTC y manejar cualquier diferencia de zona horaria en el front-end, cuando la información se presenta al usuario. Esto mantiene todo coherente y no tengo que preocuparme de si la fila se insertó a las 6:00 p. m. según la hora de la computadora de mi usuario, la hora del navegador del usuario, la hora de mi base de datos o la hora del servidor.

  • Incluir un ID campo que es único para la fila en cada tabla. La forma más fácil de hacer esto es usar un auto_increment (mysql) o identity(1,1) (servidor sql) para que la base de datos realice un seguimiento por usted. Estos valores se pueden restablecer o volver a sembrar si lo necesita.

  • Aprenda a usar normalización .

  • Aprenda qué transacciones hacer y por qué son importantes... incluso si no los usa.

  • Más información sobre los diferentes tipos de combinaciones . Esta es una de las mejores explicaciones que he visto nunca. Lo principal a lo que se debe prestar atención es si la unión debe ser una unión externa o interna.

  • Obtenga información sobre Inyección SQL y lo que es más importante, cómo para prevenirlo (ese enlace es para PHP).

  • Si está usando PHP, no use el viejo mysql_ clase. En su lugar, utilice PDO o MySQLi_ . Información...

  • Lo importante de las bases de datos es la integridad, validación y desinfección de datos. . Los usuarios querrán poner todo tipo de datos sucios y descuidados en sus tablas. ¿Es MO o Misuri? Hembra, F, mujer, niña, o si? ¿El salario es de 15,00 la hora, 50 000 al año o 3000 el cheque de pago? ¿Es 31/12/2013, 31/12/2013, 31/12/13, 31 de diciembre de 2013 o treinta y cinco de diciembre de dos mil trece?

  • Decide si quieres permitir NULL O no. Hace las cosas más complicadas debido a la lógica de triple estado y deberá verificarlo más adelante. Algunas personas deciden usar una cadena vacía en su lugar. NULO es más un estado que un valor real y significa indefinido o desconocido; el valor podría ser cualquier cosa. Yo uso null porque una cadena vacía a veces es un valor válido para un campo. Por ejemplo, configurar Middle_Initial para igualar una cadena vacía podría significar que la persona no tiene una inicial del medio o podría significar que simplemente no sabe cuál es. Para mí, estas cosas son diferentes. Para otras personas, la diferencia no importa. Solo considere los números... ¿0 es lo mismo que desconocido?

  • Al menos, sé constante.