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

SQL:creación de una tabla de relaciones con 2 auto_increment diferentes

Conceptos

Has malinterpretado algunos conceptos básicos, y las dificultades resultan de eso. Tenemos que abordar los conceptos primero, no el problema como lo percibes y, en consecuencia, tu problema desaparecerá.

ID incrementados automáticamente, que por supuesto son claves principales.

No, ellos no son. Ese es un error común. Y los problemas están garantizados.

Una ID El campo no puede ser una clave principal en el sentido inglés o técnico o relacional.

  • Claro, en SQL, puedes declarar cualquiera campo para ser una PRIMARY KEY , pero eso no lo transforma mágicamente en una clave principal en los sentidos inglés, técnico o relacional. Puedes nombrar a un chihuahua "Rottweiller", pero eso no lo transforma en un Rottweiller, sigue siendo un chihuahua. Como cualquier lenguaje, SQL simplemente ejecuta los comandos que le das, no entiende PRIMARY KEY para significar algo Relacional, simplemente golpea un índice único en la columna (o campo).

  • El problema es que, dado que ha declarado el ID ser una PRIMARY KEY , tu piensas de ella como clave principal, y puede esperar que tiene algunas de las cualidades de una Clave Primaria. Excepto por la unicidad del ID valor , no proporciona ningún beneficio. No tiene ninguna de las cualidades de una clave primaria, o cualquier tipo de clave relacional para el caso. No es una Clave en el sentido inglés, técnico o Relacional. Al declarar que una clave no es una clave, solo se confundirá y descubrirá que hay algo terriblemente mal solo cuando el usuario se queje de los duplicados en la tabla.

Las tablas relacionales deben tener fila singularidad

UNA PRIMARY KEY en un ID el campo no proporciona fila unicidad. Por lo tanto, no es una tabla relacional que contenga filas, y si no lo es, entonces es un archivo que contiene registros. No tiene la integridad, el poder (en esta etapa solo se dará cuenta del poder de combinación) o la velocidad que tiene una tabla en una base de datos relacional.

Ejecute este código (MS SQL 2008) y compruébelo usted mismo. Por favor, no se limite a leer esto y entenderlo, y luego proceda a leer el resto de esta Respuesta, este código debe ejecutarse antes de seguir leyendo . Tiene valor curativo.

    CREATE TABLE dumb_file (
        id         INT      NOT NULL  IDENTITY  PRIMARY KEY,
        name_first CHAR(30) NOT NULL,
        name_last  CHAR(30) NOT NULL
        )

    INSERT dumb_file VALUES ( "Mickey", "Mouse" )  -- succeeds
    INSERT dumb_file VALUES ( "Mickey", "Mouse" )  -- succeeds, but not intended
    INSERT dumb_file VALUES ( "Mickey", "Mouse" )  -- succeeds, but not intended

    SELECT * FROM dumb_file

Observe que tiene filas duplicadas . Las tablas relacionales deben tener filas únicas . Una prueba más de que no tiene una tabla relacional, ni ninguna de las cualidades de una.

Tenga en cuenta que en su informe, lo único que es único es el ID campo, que a ningún usuario le importa, ningún usuario ve, porque no son datos, es una tontería adicional que un "maestro" muy estúpido te dijo que pusieras en cada archivo. Tienes registro unicidad pero no fila unicidad.

En términos de los datos (los datos reales menos las adiciones extrañas), los datos name_last y name_first puede existir sin el ID campo. Una persona tiene un nombre y un apellido sin una identificación estampada en la frente.

La segunda cosa que estás usando que te confunde es AUTOINCREMENT. Si está implementando un sistema de archivo de registros sin capacidad relacional, seguro que es útil, no tiene que codificar el incremento al insertar registros. Pero si está implementando una base de datos relacional, no sirve para nada, porque nunca la usará. Hay muchas características en SQL que la mayoría de la gente nunca usa.

Acción correctiva

Entonces, ¿cómo actualiza, eleva, ese dumb_file que está lleno de filas duplicadas a una tabla relacional, para obtener algunas de las cualidades y beneficios de una tabla relacional? Hay tres pasos para esto.

  1. Necesitas entender Keys

    • Y dado que hemos progresado desde los archivos ISAM de la década de 1970, hasta el Modelo Relacional , debe comprender las claves relacionales . Es decir, si desea obtener los beneficios (integridad, potencia, velocidad) de una Base de Datos Relacional.

    Dr. EF Cood, en su RM , declaró que:

    una clave se crea a partir de los datos

    y

    las filas de una tabla deben ser únicas

    Su "clave" no se compone de los datos. Es algún parásito adicional, sin datos, causado por estar infectado con la enfermedad de su "maestro". Reconócelo como tal, y permítete la plena capacidad mental que Dios te dio (fíjate que no te pido que pienses en términos aislados o fragmentados o abstractos, todos los elementos de una base de datos deben estar integrados entre sí). Inventa una clave real a partir de los datos, y sólo a partir de los datos. En este caso, solo hay una Clave posible:(name_last, name_first).

  2. Prueba este código , declarar una restricción única sobre los datos:

         CREATE TABLE dumb_table (
            id         INT      NOT NULL  IDENTITY  PRIMARY KEY,
            name_first CHAR(30) NOT NULL,
            name_last  CHAR(30) NOT NULL
    
            CONSTRAINT UK 
                UNIQUE ( name_last, name_first )
            )
    
        INSERT dumb_table VALUES ( "Mickey", "Mouse" )  -- succeeds
        INSERT dumb_table VALUES ( "Mickey", "Mouse" )  -- fails, as intended
        INSERT dumb_table VALUES ( "Minnie", "Mouse" )  -- succeeds
    
        SELECT * FROM dumb_table
    

    Ahora tenemos exclusividad de fila . Esa es la secuencia que le sucede a la mayoría de las personas:crean un archivo que permite duplicados; no tienen idea de por qué aparecen duplicados en los menús desplegables; el usuario grita; modifican el archivo y agregan un índice para evitar engaños; van a la siguiente corrección de errores. (Pueden hacerlo correctamente o no, esa es una historia diferente).

  3. El segundo nivel. Para personas pensantes que piensan más allá de los arreglos. Dado que ahora tenemos unicidad de fila, ¿cuál es el propósito del ID? campo, ¿por qué lo tenemos? Ay, porque el chihuahua se llama Rotty y nos da miedo tocarlo.

    La declaración de que es una PRIMARY KEY es falso, pero permanece, provocando confusión y falsas expectativas. La única clave genuina que existe es el (name_last, name_fist), y es una clave alternativa en este punto.

    Por lo tanto, el ID el campo es totalmente superfluo; y también lo es el índice que lo sustenta; y también lo es el estúpido AUTOINCREMENT; y también lo es la declaración falsa de que es una PRIMARY KEY; y cualquier expectativa que pueda tener de ella es falsa.

    Por lo tanto, elimine el ID superfluo campo. Prueba este código :

        CREATE TABLE honest_table (
            name_first CHAR(30) NOT NULL,
            name_last  CHAR(30) NOT NULL
    
            CONSTRAINT PK 
            PRIMARY KEY ( name_last, name_first )
            )
    
        INSERT honest_table VALUES ( "Mickey", "Mouse" )  -- succeeds
        INSERT honest_table VALUES ( "Mickey", "Mouse" )  -- fails, as intended
        INSERT honest_table VALUES ( "Minnie", "Mouse" )  -- succeeds
    
        SELECT * FROM honest_table
    

    Funciona bien, funciona según lo previsto, sin los campos e índices superfluos.

    Recuerde esto y hágalo bien cada vez.

falsos maestros

En estos últimos tiempos, como se aconseja, tendremos muchos de ellos. Fíjate bien, los "maestros" que propagan ID columnas, en virtud de la evidencia detallada en esta publicación, simplemente no entienden el modelo relacional o Bases de datos relacionales. Especialmente aquellos que escriben libros al respecto.

Como se evidencia, están atascados en la tecnología ISAM anterior a 1970. Eso es todo lo que entienden, y eso es todo lo que pueden enseñar. Utilizan un contenedor de base de datos SQL, para facilitar el acceso, la recuperación, la copia de seguridad, etc., pero el contenido es puro sistema de archivo de registros sin integridad relacional, potencia o velocidad. AFAIC, es un fraude grave.

Además de ID campos, por supuesto, hay varios elementos que son conceptos clave relacionados o no, que tomados en conjunto, me hacen llegar a una conclusión tan grave. Esos otros elementos están más allá del alcance de esta publicación.

Un par de idiotas en particular está montando un asalto en First Normal Form. Pertenecen al manicomio.

Respuesta

Ahora, el resto de tu pregunta.

¿Hay alguna manera de que pueda crear una tabla relacional sin perder las funciones de incremento automático?

Esa es una oración que se contradice a sí misma. Confío en que entenderá de mi explicación, las tablas relacionales no tienen necesidad para AUTOINCREMENT "características"; si el archivo tiene AUTOINCREMENT , no es una tabla relacional.

AUTOINCREMENT es bueno solo para una cosa:si, y solo si, desea crear una hoja de cálculo de Excel en el contenedor de la base de datos SQL, repleta de campos llamados A, B, y C, en la parte superior y registre los números en el lado izquierdo. En términos de base de datos, ese es el resultado de un SELECT, una vista plana de los datos, que no la fuente de datos, que está organizado (Normalizado).

Otra solución posible (pero no preferida) puede ser que haya otra clave principal en la primera tabla, que es el nombre de usuario del usuario, sin una declaración de incremento automático, por supuesto. ¿Es inevitable?

En el trabajo técnico, no nos importan las preferencias, porque eso es subjetivo y cambia todo el tiempo. Nos preocupamos por la corrección técnica, porque eso es objetivo y no cambia.

Sí, es inevitable. Porque es solo cuestión de tiempo; número de errores; número de "no se puede hacer"; número de gritos de usuarios, hasta que enfrentas los hechos, superas tus falsas declaraciones y te das cuenta de que:

  • la única forma de asegurarse de que el usuario fila son únicos, que los nombres de usuario son únicos, es declarar un UNIQUE restricción en él

  • y deshacerse de user_id o id en el archivo de usuario

  • que promueve user_name a PRIMARY KEY

Sí, porque todo su problema con la tercera tabla, no por casualidad, se elimina entonces.

Esa tercera tabla es una tabla asociativa . La única clave requerida (clave principal) es una combinación de las dos claves principales principales. Eso asegura la singularidad de las filas , que se identifican por sus claves, no por sus IDs.

Te lo advierto porque los mismos "maestros" que te enseñaron el error de implementar ID campos, enseña el error de implementar ID campos en la Tabla Asociativa, donde, al igual que con una tabla ordinaria, es superfluo, no sirve para nada, introduce duplicados y causa confusión. Y es doblemente superfluo porque las dos claves que proporciona ya están ahí, mirándonos a la cara.

Ya que no entienden el RM , o términos relacionales, llaman a las tablas asociativas tablas de "vínculo" o "mapa". Si tienen un ID campo, de hecho, son archivos.

Tablas de consulta

ID los campos son particularmente Algo estúpido de hacer para tablas de consulta o de referencia. La mayoría de ellos tienen códigos reconocibles, no hay necesidad de enumerar la lista de códigos en ellos, porque los códigos son (deberían ser) únicos.

Además, tener los códigos en las tablas secundarias como FK es algo bueno:el código es mucho más significativo y, a menudo, ahorra una unión innecesaria:

    SELECT ...
        FROM child_table           -- not the lookup table
        WHERE gender_code = "M"    -- FK in the child, PK in the lookup

en lugar de:

    SELECT ...
        FROM child_table
        WHERE gender_id = 6        -- meaningless to the maintainer

o peor:

    SELECT ...
        FROM child_table C         -- that you are trying to determine
        JOIN lookup_table L
            ON C.gender_id = L.gender_id
        WHERE L.gender_code = "M"  -- meaningful, known

Tenga en cuenta que esto es algo que uno no puede evitar:necesita unicidad en el código de búsqueda y singularidad en la descripción. Ese es el único método para evitar duplicados en each de las dos columnas:

    CREATE TABLE gender (
        gender_code  CHAR(2)  NOT NULL,
        name         CHAR(30) NOT NULL

        CONSTRAINT PK 
            PRIMARY KEY ( gender_code )

        CONSTRAINT AK 
            UNIQUE ( name )
        )

Ejemplo completo

A partir de los detalles de su pregunta, sospecho que tiene problemas de sintaxis SQL y definición de FK, por lo que le daré la solución completa que necesita como ejemplo (ya que no ha proporcionado definiciones de archivo):

    CREATE TABLE user (                 -- Typical Identifying Table
        user_name  CHAR(16) NOT NULL,   -- Short PK
        name_first CHAR(30) NOT NULL,   -- Alt Key.1
        name_last  CHAR(30) NOT NULL,   -- Alt Key.2
        birth_date DATE     NOT NULL    -- Alt Key.3

        CONSTRAINT PK                   -- unique user_name
            PRIMARY KEY ( user_name )

        CONSTRAINT AK                   -- unique person identification
            PRIMARY KEY ( name_last, name_first, birth_date )
        )

    CREATE TABLE sport (                  -- Typical Lookup Table
        sport_code  CHAR(4)  NOT NULL,    -- PK Short code
        name        CHAR(30) NOT NULL     -- AK

        CONSTRAINT PK 
            PRIMARY KEY ( sport_code )

        CONSTRAINT AK 
            PRIMARY KEY ( name )
        )

    CREATE TABLE user_sport (           -- Typical Associative Table
        user_name  CHAR(16) NOT NULL,   -- PK.1, FK
        sport_code CHAR(4)  NOT NULL,   -- PK.2, FK
        start_date DATE     NOT NULL

        CONSTRAINT PK 
            PRIMARY KEY ( user_name, sport_code )

        CONSTRAINT user_plays_sport_fk
            FOREIGN KEY     ( user_name )
            REFERENCES user ( user_name )

        CONSTRAINT sport_occupies_user_fk
            FOREIGN KEY      ( sport_code )
            REFERENCES sport ( sport_code )
        )

Allí, la PRIMARY KEY la declaración es honesta, es una clave principal; sin ID; sin AUTOINCREMENT; sin índices adicionales; sin filas duplicadas; sin expectativas erróneas; sin problemas consecuentes.

Modelo de datos

Aquí está el modelo de datos para ir con las definiciones.

  • Modelo de datos deportivos de usuario de ejemplo

  • Si no está acostumbrado a la notación, tenga en cuenta que cada pequeña marca, muesca y marca, las líneas sólidas frente a las discontinuas, las esquinas cuadradas frente a las redondas, significan algo muy específico. Consulte la Notación IDEF1X .

  • Una imagen vale mas que mil palabras; en este caso, una imagen de queja estándar vale más que eso; uno malo no vale ni el papel en el que está dibujado.

  • Por favor revise cuidadosamente las Frases Verbales, comprenden un conjunto de Predicados. El resto de los Predicados se puede determinar directamente a partir del modelo. Si esto no está claro, por favor pregunte.