2011-09-05 7 views
6

Hola, tengo una breve pregunta sobre el diseño de la base de datos. También probé la búsqueda pero no puedo encontrar lo que estoy buscando. Así que aquí está mi pregunta:1: relación N donde N debe ser al menos una entrada

Tengo dos tablas de la base de la idea y medios (1: N). Entonces, básicamente, esto significa que una idea puede tener ninguno, uno o varios medios. PERO me preguntaba si es posible definir la tabla en la que cada idea debe tener al menos un medio. Si esto es posible, ¿cómo puedo lograr esto con MS SQL Server 2008?

Espero que alguien me pueda ayudar.

mucho Thx por su ayuda

ACTUALIZACIÓN: esto es lo que parece en la actualidad

enter image description here

+2

No estoy seguro de cómo podría hacer esto manteniendo 'Media' en una tabla separada: ¿cómo va a insertar los datos? Primero debe insertar en una tabla, luego en la segunda. Lo que puedes intentar es colocar los primeros "Medios" en la "Idea" (des-normalización) y declarar los campos como "no nulos", pero no lo recomendaría. Es posible que esté mejor con un poco de lógica en el código en lugar de la base de datos. –

+0

Estoy de acuerdo con Aleks. Creo que esta es una regla de negocios que pertenece a un nivel intermedio en alguna parte, no en la base de datos. – David

+0

@Aleks asociar un FK NOT NULL de Idea a Media no es infrecuente. Es simple, y sí, primero tendrá que llenar los medios. – vol7ron

Respuesta

2

En primer lugar, existe una regla general de diseño que una tabla modela ya sea un tipo de entidad única o una relación entre tipos de entidades, pero no ambas. Por lo tanto, imagino tres tablas, Media (entidad), Idea (entidad) y IdeasMedia (relación). PD. sabes que el singular de 'media' es 'medio', ¿verdad? :)

He aquí algunos DDL de SQL-92 estándar que se centra en sólo teclas:

CREATE TABLE Media (MediaID INTEGER NOT NULL UNIQUE); 
CREATE TABLE Idea (IdeaID INTEGER NOT NULL UNIQUE); 
CREATE TABLE IdeasMedia 
(
MediaID INTEGER NOT NULL REFERENCES Media (MediaID), 
IdeaID INTEGER NOT NULL REFERENCES Idea (IdeaID) 
); 
CREATE ASSERTION Idea_must_have_media DEFERRABLE 
    CHECK (
      NOT EXISTS (
         SELECT * 
         FROM Idea AS i 
         WHERE NOT EXISTS (
             SELECT * 
              FROM IdeasMedia AS im 
              WHERE im.MediaID = i.IdeaID 
             ) 
        ) 
     ); 

Hay un escenario 'huevo y la gallina' aquí: no se puede crear una idea con y sin una referencia a IdeasMedia pero puede ¡No cree un IdeasMedia sin crear un Idea!

La solución ideal (basada en conjuntos) sería que SQL Standard admitiera asignaciones múltiples, p.

INSERT INTO Media (MediaID) VALUES (22), 
    INSERT INTO Idea (IdeaID) VALUES (55), 
    INSERT INTO IdeasMedia (MediaID, IdeaID) VALUES (22, 55); 

donde el punto y coma indica el límite instrucción SQL a la que se comprueban las restricciones de puntos y las comas que denotan los subsentencias.

Lamentablemente, no hay planes para agregar este paradigma basado en conjuntos al estándar SQL.

La solución (procedimiento) de SQL-92 para esto es la siguiente:

BEGIN TRANSACTION; 
INSERT INTO Media (MediaID) VALUES (22); 
SET CONSTRAINTS Idea_must_have_media DEFERRED; 
-- omit the above if the constraint was declared as INITIALLY DEFERRED. 
INSERT INTO Idea (IdeaID) VALUES (55); 
INSERT INTO IdeasMedia (MediaID, IdeaID) VALUES (55, 22); 
SET CONSTRAINTS Idea_must_have_media IMMEDIATE; 
-- above may be omitted: constraints are checked at commit anyhow. 
COMMIT TRANSACTION; 

Lamentablemente, SQL Server no admite ni CREATE ASSERTIONCHECK restricciones que pueden hacer referencia a otras tablas ni limitaciones diferibles!

Personalmente, me gustaría manejar esto en SQL Server como sigue:

  • Crear 'ayudante' procedimientos almacenados para agregar, modificar y eliminar Ideas y sus respectivos IdeasMedia relaciones.
  • Elimina los privilegios de actualización de las tablas para obligar a los usuarios a usar los procesos .
  • Posiblemente use desencadenadores para manejar escenarios al eliminar Media y Idea entidades.

Ciertamente, esta implementación (nuevo procedimiento) está muy lejos del enfoque basado en el ideal establecido, lo que probablemente explica por qué la mayoría de los codificadores de SQL hacen la vista gorda a la exigencia de una relación 1: 1..N y en su lugar asume que el diseñador significó 1: 0..N !!

+0

¡¡Hola onedaywhen gracias por tu excelente respuesta !!! Su respuesta es muy extensa y describe diferentes enfoques para lograr una solución a mi problema. Realmente aprecio eso. Aun así, todas las soluciones son bastante feas. He decidido manejar esto en mi lógica comercial. Y thx para la corrección gramatical;) – MUG4N

1

se crea una (clave externa) FK en Idea a PK (clave principal) en Media. Al mismo tiempo, aplique una restricción NOT NULL al FK.

Si ya tiene datos de la tabla, see here


Para ilustrar:

Media    Idea 
-----    ---- 
id | type   id | description  | media_id 
----+-----   ----+-------------------+---------- 
1 | TV    90 | advertise  | 2 
2 | Magazine  90 | advertise  | 1 
3 | Mail   91 | superbowl party | 1 
        91 | superbowl party | 3 

No estoy diciendo que esto es un gran diseño, y definitivamente no sé lo que su las tablas se almacenan (indicado por mi pobre ejemplo), pero la idea no puede existir sin una entrada de medios para enlazar. No hay un enlace hacia adelante y hacia atrás, usted está pidiendo 1: N, no N: N, que puede querer.

Al pensar en los nombres de la tabla, parece que su idea es al revés. Creo que tendrías 1: Media to N: Ideas en lugar de lo contrario.


CREATE TABLE idea (
    id  integer 
    , media_id integer NOT NULL REFERENCES media 
) 

--or-- 

CREATE TABLE idea (
    id   integer 
    , media_id NOT NULL 
    , FOREIGN KEY (media_id) REFERENCES media 
); 

Nota: Esto no normalizado, por lo que tendría una tercera tabla para que coincida con los puntos de unión.

+1

¿Entonces las dos tablas tienen claves foráneas entre sí? Eso sería un poco extraño ¿no? Y también sufre el problema de 'huevo y gallina' especificado por Aleks G. – David

+0

Esto significa referencia cruzada ... He oído cosas malas sobre referencias cruzadas. ¿Es esta una buena práctica común? ¿O hay algunas mejores prácticas para esta situación? – MUG4N

+0

@David, ¿qué quieres decir? ¿Por qué tendrías FK entre vosotros, solo hay un FK de una sola vía de Idea a Media – vol7ron

Cuestiones relacionadas