Está utilizando la herencia (también conocida en el modelado de relaciones entre entidades como "subclase" o "categoría"). En general, hay 3 formas de representarlo en la base de datos:
- "Todas las clases en una mesa": tener sólo una mesa de "cobertura" a los padres y todas las clases hijas (es decir, con todos los padres e hijos columnas), con una restricción CHECK para asegurar que el subconjunto correcto de campos no sea NULL (es decir, que dos niños diferentes no se "mezclen").
- "Clase de hormigón por tabla": Tenga una tabla diferente para cada niño, pero no una tabla principal. Esto requiere que las relaciones de los padres (en su caso, Inventario < - Almacenamiento) se repitan en todos los niños.
- "Clase por tabla": Tener una tabla primaria y una tabla separada para cada hijo, que es lo que está intentando hacer. Esto es más limpio, pero puede costar cierto rendimiento (sobre todo cuando se modifican datos, no tanto cuando se realiza la consulta porque se puede unir directamente desde el niño y omitir al padre).
Por lo general prefieren la tercera aproximación, pero hacer cumplir tanto la presencia y la exclusividad de un niño a nivel de aplicación. Hacer cumplir ambos a nivel de la base de datos es un poco engorroso, pero se puede hacer si el DBMS admite restricciones diferidas. Por ejemplo:
![enter image description here](https://i.stack.imgur.com/5O7FQ.png)
CHECK (
(
(VAN_ID IS NOT NULL AND VAN_ID = STORAGE_ID)
AND WAREHOUSE_ID IS NULL
)
OR (
VAN_ID IS NULL
AND (WAREHOUSE_ID IS NOT NULL AND WAREHOUSE_ID = STORAGE_ID)
)
)
Esto hará cumplir tanto la exclusividad (debido a la CHECK
) y la presencia (debido a la combinación de CHECK
y FK1
/FK2
) del niño.
Desafortunadamente, MS SQL Server does not support deferred constraints, pero es posible que pueda "ocultar" toda la operación detrás de los procedimientos almacenados y prohibir a los clientes modificar las tablas directamente.
Sólo la exclusividad puedan aplicarse sin limitaciones diferidos:
![enter image description here](https://i.stack.imgur.com/oOr2D.png)
El STORAGE_TYPE
es un discriminador de tipo, por lo general un número entero para ahorrar espacio (En el ejemplo anterior, 0 y 1 son " conocido "para su aplicación e interpretado en consecuencia).
Las columnas VAN.STORAGE_TYPE
y WAREHOUSE.STORAGE_TYPE
se pueden calcular (también conocidas como "calculadas") para ahorrar espacio de almacenamiento y evitar la necesidad de CHECK
s.
--- --- EDITAR
columnas calculadas trabajarían bajo SQL Server como esto:
CREATE TABLE STORAGE (
STORAGE_ID int PRIMARY KEY,
STORAGE_TYPE tinyint NOT NULL,
UNIQUE (STORAGE_ID, STORAGE_TYPE)
);
CREATE TABLE VAN (
STORAGE_ID int PRIMARY KEY,
STORAGE_TYPE AS CAST(0 as tinyint) PERSISTED,
FOREIGN KEY (STORAGE_ID, STORAGE_TYPE) REFERENCES STORAGE(STORAGE_ID, STORAGE_TYPE)
);
CREATE TABLE WAREHOUSE (
STORAGE_ID int PRIMARY KEY,
STORAGE_TYPE AS CAST(1 as tinyint) PERSISTED,
FOREIGN KEY (STORAGE_ID, STORAGE_TYPE) REFERENCES STORAGE(STORAGE_ID, STORAGE_TYPE)
);
-- We can make a new van.
INSERT INTO STORAGE VALUES (100, 0);
INSERT INTO VAN VALUES (100);
-- But we cannot make it a warehouse too.
INSERT INTO WAREHOUSE VALUES (100);
-- Msg 547, Level 16, State 0, Line 24
-- The INSERT statement conflicted with the FOREIGN KEY constraint "FK__WAREHOUSE__695C9DA1". The conflict occurred in database "master", table "dbo.STORAGE".
Desafortunadamente, SQL Server requiere de una columna calculada que se utiliza en una extranjera clave que se PERSISTERÁ. Es posible que otras bases de datos no tengan esta limitación (por ejemplo, las columnas virtuales de Oracle), lo que puede ahorrar algo de espacio de almacenamiento.
Por favor, evaluar a fondo si realmente necesita una relación uno a uno. La mayoría de las veces cuando piensas que necesitas uno, realmente no. –
Use EER. La clave aquí es identificar el tipo de relación 'is a',' has'/'pertenece a', o son los subtipos del mismo supertipo. Luego reduzca sus entidades a tablas. – Oybek
Ahh vale, bueno, entonces Storage Table es una superclase y Van/Warehouse Tables son subtipos, pero ¿ahora qué? lol – Luckyl337