Estoy construyendo una base de datos herramienta de gestión para un cliente para utilizar en su propio, y estoy teniendo algunos problemas tratando con la posibilidad de la actualización de primaria/claves únicas. Así que, dado que los datos para la actualización se pasa por un script PHP en cada fila de la base, he aquí lo que he encontrado (de «inmediatamente» a «después de algún tiempo»):

  1. DELETE/INSERT en lugar de la ACTUALIZACIÓN (horrible, yo ahora…):

    DELETE FROM table WHERE unique_key=x;
    DELETE FROM table WHERE unique_key=y;
    INSERT INTO table VALUES (unique_key=y, field=record1), (unique_key=x, field=record2);
  2. Alterar mi principal o clave única y, a continuación, sustituya, con el valor modificado:

    UPDATE table SET unique_key=x* WHERE unique_key=x;
    UPDATE table SET unique_key=y* WHERE unique_key=y;
    UPDATE table SET unique_key=y WHERE unique_key=x*;
    UPDATE table SET unique_key=x WHERE unique_key=y*;
  3. Agregar un no modificables auto_increment campo «id» a todos mis tablas, que actúan como un sustituto de la clave principal

Como ahora, estoy en la ruta de la adición de un campo «id» de todo. Otras opciones?

  • Yo no soy realmente la comprensión de lo que el caso de uso, está aquí. ¿Por qué usted necesita para actualizar las claves primarias como la que sobre una base regular? Estoy pensando que tal vez su problema es más con el diseño del esquema, a continuación, la mecánica de cómo se va a actualizar a estas filas. Usted menciona la opción número tres (que es MUY común la práctica de bases de datos relacionales) como si es una idea de último momento. ¿Por qué no sus tablas han inmutable de las claves principales para empezar?
  • Gracias por tu respuesta. Seguramente la base de datos podría haber sido diseñado mejor, estoy empezando. En cuanto a la frecuencia de la actualización de la clave, si alguno se hará cada ahora y entonces, el hecho es que no podía, y me ha preguntado por algo que les permiten modificar tanto como sea posible (debe ser un mini-phpmyAdmin, para decirlo).
  • En la práctica no existe tal cosa como una «inmutable» clave. Sustituto de los valores de la clave, a veces cambiar demasiado. La estabilidad es una propiedad deseable en la elección y diseño de las teclas; la inmutabilidad no es.
InformationsquelleAutor siberius.k | 2013-05-08

2 Comentarios

  1. 1

    La actualización de una clave principal no es un problema; todos los valores en SQL (y en el modelo relacional) se supone para ser actualizable.

    El problema parece ser el intercambio de claves primarias, que

    • no tiene sentido para mí si utiliza claves de suplente (porque son de sentido, por lo que las actualizaciones no son necesarios) y que
    • no tiene sentido para mí si utiliza claves naturales, debido a que como el intercambio de mi StackOverflow identificador de usuario con el tuyo.

    La adición de una columna «ID» de cada tabla, no le ayuda. El «unique_key» columna todavía tiene que ser declarado único. La adición de una columna «ID» no cambia el requisito de negocio.

    Que podría intercambiar los valores de clave principal si MySQL compatible diferido restricciones. (Diferido restricciones son una característica estándar de SQL.) Pero MySQL no soporta esa función. En PostgreSQL, por ejemplo, usted podría hacer esto.

    create table test (
      unique_key char(1) primary key deferrable initially immediate,
      other_column varchar(15) not null
    );
    
    insert into test values 
    ('x', 'record2'),
    ('y', 'record1');
    
    begin;
    set constraints test_pkey deferred;
    update test set unique_key = 'y' where other_column = 'record2';
    update test set unique_key = 'x' where other_column = 'record1';
    commit;
    
    select * from test;
    
    unique_key  other_column
    --
    y           record2
    x           record1
    • Ya lo tienes, el intercambio de valores únicos es exactamente el punto, y la adición de un sustituto llaves no resolver eso. Tal vez me vea por qué usted dice que no va a tener sentido de todos modos… yo en su lugar puede actualizar todos los otros (no único) de los campos en lugar de eso, ¿no? UPDATE table SET field='record2' WHERE unique_key=x; , Simplemente tendría que dejar de PHP encontrar de intercambio de los casos y gestionarlos con una consulta adecuada.
    • En el caso general, usted no puede cambiar detalles de la actualización de todo lo que pero la clave principal ya que, en el caso general, que podría implicar el intercambio de otro candidato claves. (Es el mismo problema que nos encontramos por la adición de una clave suplente; prorrogable restricciones de trabajo en ambos casos.) Estoy tratando de imaginar un caso en el que este tipo de «identidad » intercambio» tiene sentido, pero estoy fallando. ¿Qué te imaginas?
    • Así, por fin he conseguido configurar un script de PHP que la comprobación de duplicados y los swaps entre los entrantes valores modificados, se compara con la de una copia temporal de los datos originales, y construye la consulta correspondiente. Después de todo, no vale la pena, tienes razón. Lo que me hizo imaginar es básicamente un error que cometí, la construcción de, al menos, dos de la tabla con un concatenar campo como clave principal en lugar de la configuración de una clave principal múltiple, además de tratar de hacer que funcione whaterver les gustaría modificar en el futuro, pero al final las claves primarias de hecho, deberían ser no modificables. Gracias por su comprensión.
    • «las claves primarias de hecho, deberían ser no modificables» me gustaría estar en desacuerdo con que; he sido a través de varias fusiones, donde suplente PKs tuvo que ser cambiado en combinar datos. Yo simplemente no puede imaginarse un caso en el que intercambio de ellos no tiene sentido en el mundo real. De todos modos, me alegro de que haya encontrado una solución.
  2. 0

    Usted debería ser capaz de utilizar una expresión CASE para hacer este tipo de actualización. Por ejemplo:

    UPDATE tbl SET col =
        CASE    WHEN col = 1 THEN 2
                WHEN col = 2 THEN 1
        END
    WHERE col IN (1,2);

    (código no probado)

Dejar respuesta

Please enter your comment!
Please enter your name here