restricciones - llave primaria y foranea sql
¿Puede la clave externa ser nula? (4)
Esta pregunta ya tiene una respuesta aquí:
- ¿Puede una clave externa ser NULL y / o duplicarse? 7 respuestas
En nuestro proyecto de base de datos, tenemos una tabla Sale
que tiene una clave principal y dos claves externas exclusivas: Vehicle_ID
y Piece_ID
. Por ejemplo, si vendemos un vehículo, necesitamos Vehicle_ID
como una clave externa pero no Piece_ID
. ¿Podemos poner NULL en Piece_ID
, podría una clave externa ser nula? ¿O hay una forma de hacer este trabajo?
Gracias.
Responder:
Sí, puede hacer eso: haga que los FK sean NULL-able, pero agregue un CHECK para asegurarse de que uno de ellos contenga un valor que no sea NULL.
Elaboración:
Un FK puede ser NULL-able, que modela una relación 1..0: N. En otras palabras, una fila "hija" puede (pero no es obligatoria) tener una fila "principal".
Una clave foránea NOT NULL modela una relación 1: N. En otras palabras, cada niño debe tener un padre.
Cuando un FK es compuesto 1 , y al menos uno de sus campos es NULL-able, una mezcla de valores NULL y no NULL se maneja de una manera especial:
- Si el FK es MATCH FULL, todos los valores deben ser NULL o todos los valores deben ser no NULL y coincidir con alguna fila principal.
- Si el FK es MATCH PARTIAL, solo aquellos valores que no sean NULL deben coincidir con alguna fila principal (se ignoran los NULL).
- Si el FK es MATCH SIMPLE, todos los valores son no NULL y deben coincidir con alguna fila principal, o hay al menos un valor NULL (en cuyo caso no es necesario que los no NULL coincidan).
La mayoría de los DBMS predeterminados a MATCH SIMPLE (con la notable excepción de MS Access ) y la mayoría no admiten nada más que el valor predeterminado.
1 Que no tienes aquí, solo mencionarlo para completarlo.
Dependiendo de lo que quiera decir con "claves foráneas exclusivas", podría pensar en vehículos y piezas como dos subclases de una superclase mayor, denominarlas artículos vendibles.
Si utiliza un patrón de diseño denominado "herencia de tabla de clase", tendrá tres tablas, una para la superclase y otra para cada tabla de subclase. Si además, utiliza un diseño llamado "clave primaria compartida", puede usar la misma clave principal para las tres tablas.
Esto permitiría que su tabla de ventas tenga una única clave externa, Saleable_Item_Id, que haga referencia a la tabla Saleable_Item y también al vehículo o la tabla Piece, según el caso. Esto podría funcionar mejor para usted que el diseño existente.
google "inheritance de tabla de clase" y "clave primaria compartida" para más detalles.
La columna (o columnas) de una clave principal debe ser NOT NULL. Un registro no puede ser identificado de forma exclusiva por un NULL. Por lo tanto, las columnas de ID en el extremo referenciado de la clave externa se deben definir como NOT NULL.
Sin embargo, es una decisión de diseño legítima para una relación de clave externa ser opcional, y la forma de representarlo es haciendo que el extremo de referencia de la clave sea opcional, es decir, que permita valores NULL.
En términos de modelado de datos, lo que ha descrito es un arco (exclusivo): "una tabla ... con dos o más claves externas donde una y solo una de ellas puede ser no nula". En el modelado lógico los arcos son perfectamente aceptables, pero existe un fuerte cuerpo de opinión a favor de implementarlos como tablas separadas. En su escenario, se trataría de una tabla de ventas genérica más dos tablas de subtipos, ''VehicleSale and ''PieceSale
.
Las ventajas de la implementación de tabla por separado son:
- más fácil de aplicar las restricciones de clave externa;
- es más fácil agregar columnas adicionales relacionadas con (por ejemplo) ventas de vehículos que no se aplican a la venta de piezas;
- más fácil extender el modelo con subtipos adicionales;
- modelo de datos más claro, que puede simplificar el desarrollo de aplicaciones.
Sin embargo, las ventajas no son todas de una sola vía. Si bien es bastante fácil garantizar que una Sale
aplique a un VehicleSale
en VehicleSale
o un PieceSale
en PieceSale
pero no a ambos, hacer cumplir una regla de que una Sale
debe ser un registro de niño en realidad se vuelve bastante desagradable.
Entonces, el consejo predominante es que un arco exclusivo está equivocado, y generalmente es un buen consejo. Pero no es tan claro como algunos hacen.
Oracle no debería quejarse si tiene una clave externa nula.
¿Te encontraste con algunos errores?