Pregunta

En una base de datos que estoy tener que diseñar para MS Access, he una tabla llamada "Mediciones", que almacena ciertos parámetros de medición (valores de medición, Desviación estándar, etc.) - cada fila tiene un ID número entero como su primaria la clave.

Otras tablas a continuación enlazan a esta mesa de medición con relaciones de clave externa. Algunas tablas contienen dos campos diferentes "measurementID", que tanto enlace a esta tabla una medición. Sin embargo, cada medida solo deben vinculado a por un de estos campos.

¿Cómo puedo hacer cumplir una restricción de unicidad en varios campos de varias tablas? Sé que hay una manera?

¿Fue útil?

Solución

Estas limitaciones pueden de hecho ser implementados en ACE / JET mediante restricciones CHECK.

La persona que dijeron que por lo general utilizar disparadores para este tipo de cosas es posible, no es consciente de la diferencia entre las limitaciones CHECK en ACE / Jet y SQL Server, respectivamente: en SQL Server no pueden contener subconsultas, lo que significa que no pueden referirse a valores en otras filas de la misma tabla o con otras tablas, mientras que en la ECA / Jet no puede.

En un ideal (pero todavía AFAIK inexistente) SQL-92 del producto, la singularidad descrito sería implementado usando un ASSETION, siendo a nivel de esquema. Debido a las restricciones CHECK son a nivel de tabla y sólo se comprueban cuando la mesa en la que se definen son UPDATEd o INSERTed, que tendría que poner limitaciones CHECK apropiadas en toda la tabla de referencia (lo mismo se aplicaría a los factores desencadenantes de SQL Server). Aquí está un ejemplo rápido:

CREATE TABLE Parent 
(
   parent_ID INTEGER NOT NULL IDENTITY UNIQUE, 
   data_col INTEGER NOT NULL
)
;
CREATE TABLE Child1
(
   parent_ID INTEGER NOT NULL
      REFERENCES parent (parent_ID), 
   data_col INTEGER NOT NULL
)
;
CREATE TABLE Child2
(
   parent_ID INTEGER NOT NULL
      REFERENCES parent (parent_ID), 
   data_col INTEGER NOT NULL
)
;
ALTER TABLE Child1 ADD
   CONSTRAINT child1__no_dups_in_child2
   CHECK (NOT EXISTS (
                      SELECT * 
                        FROM Child1 AS C1
                             INNER JOIN Child2 AS C2
                                ON C1.parent_ID = C2.parent_ID
                     ))
;
ALTER TABLE Child2 ADD
   CONSTRAINT child2__no_dups_in_child1
   CHECK (NOT EXISTS (
                      SELECT * 
                        FROM Child1 AS C1
                             INNER JOIN Child2 AS C2
                                ON C1.parent_ID = C2.parent_ID
                     ))
;

Sin embargo, me pregunto si tiene subclases (es decir, cada entidad representada por un ID se puede escribir), en cuyo caso usted debe ser capaz de utilizar FOREIGN KEYs y limitaciones a nivel de fila CHECK (o reglas de validación si son más cómodo con la interfaz de MS Access a SQL DLL que se requiere para las restricciones CHECK). La lógica será más fácil de implementar que las limitaciones CHECK a nivel de tabla, simplemente ver para los ciclos de acciones referenciales CASCADE. Aquí hay otro ejemplo sencillo:

CREATE TABLE Parent 
(
   parent_ID INTEGER NOT NULL IDENTITY, 
   child_type VARCHAR(4) NOT NULL, 
   CONSTRAINT child_type__values 
      CHECK (child_type IN ('Boy', 'Girl')), 
   UNIQUE (child_type, parent_ID)
)
;
CREATE TABLE Girls
(
   parent_ID INTEGER NOT NULL, 
   child_type VARCHAR(4) DEFAULT 'girl' NOT NULL, 
   CONSTRAINT girl_child_type__must_be_girl
      CHECK (child_type = 'girl'),
   FOREIGN KEY (child_type, parent_ID)
      REFERENCES Parent (child_type, parent_ID), 
   data_col INTEGER NOT NULL
)
;
CREATE TABLE Boys
(
   parent_ID INTEGER NOT NULL, 
   child_type VARCHAR(4) DEFAULT 'boy' NOT NULL, 
   CONSTRAINT boy_child_type__must_be_boy
      CHECK (child_type = 'boy'),
   FOREIGN KEY (child_type, parent_ID)
      REFERENCES Parent (child_type, parent_ID), 
   data_col INTEGER NOT NULL
)
;

Otros consejos

motor ACE / Microsoft Jet no es compatible con disparadores, que es como se haría normalmente poner en práctica este tipo de funcionalidad.

EDIT:. Como ha señalado @onedaywhen, JET 4.0 en adelante hace soportar restricciones de comprobación, pero no es fácil de implementar una restricción de tipo XOR a través de dos columnas

Si está usando las formas de acceso, se puede implementar el evento de actualización antes de la forma y revisar sus criterios de restricción.

Mitch tiene razón acerca de lo que es posible en el acceso. Sin embargo, suponiendo que tiene una BL algún lugar, esto está acercándose a lo que es legítima como norma de trabajo. Eso es lo que haría más probable es que sí.

Teniendo en cuenta que se está diseñando esta base de datos. ¿Está seguro de que sus estructuras de tabla está siguiendo las reglas de normalización estándar.

Suena una estructura inusual para una fila de la tabla A para poder hacer referencia a dos filas en las mediciones de la tabla, dependiendo de qué campo A.row que está viendo. Tengo la sensación de que los datos en la tabla de Medicion realmente tiene que ser dividido en dos o más tablas.

Yo mismo soy cuidadoso de factores desencadenantes y restricciones de comprobación, sobre todo porque he desarrollado la mayor parte de mis aplicaciones sin ellos (Access / Jet y MySQL / MyISAM). Estoy de acuerdo con BobClegg que esto suena como una situación supertipo / subtipo. En ese caso, tendrá que utilizar una tabla de unión con un índice único en la clave externa y una columna que indica el tipo de medición que era. El índice único en el FK impediría la adición de un segundo tipo. También significaría que no tendría campos vacíos en su registro principal. Ciertamente, un campo numérico vacía no es un problema de almacenamiento, sino dos campos que son exclusivos siempre se ve como un error de diseño para mí.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top