Question

J'ai une colonne de texte qui ne devrait avoir 1 de 3 cordes possibles. Pour mettre une contrainte, je dois faire référence à une autre table. Puis-je mettre à la place les valeurs de la contrainte directement sur la colonne sans se référer à une autre table?

Était-ce utile?

La solution

Si cela est SQL Server, Oracle ou PostgreSQL , oui, vous pouvez utiliser un check constraint.

Si c'est MySQL, check constraints sont reconnus, mais pas appliquées. Vous pouvez utiliser un enum , cependant. Si vous avez besoin d'une liste séparée par des virgules, vous pouvez utiliser un set .

Cependant, ce qui est généralement mal vu, car il est certainement pas facile à entretenir. Il suffit de mieux pour créer une table de consultation et d'assurer l'intégrité référentielle par là.

Autres conseils

En plus de la contrainte de vérification et le type de données ENUM autre mention, vous pouvez également écrire un déclencheur pour faire respecter votre restriction désirée.

Je ne recommande pas nécessairement un élément déclencheur comme bon solution, je suis juste une autre option indiquant qui répond à vos critères de ne pas référence à une table de consultation.

Mon habitude est de définir des tables de consultation au lieu d'utiliser des contraintes ou des déclencheurs, lorsque la règle est simplement de limiter une colonne à un ensemble de valeurs finies. L'impact sur les performances de la vérification par rapport à une table de consultation est pas pire que d'utiliser les contraintes CHECK ou déclencheurs, et il est beaucoup plus facile à gérer lorsque l'ensemble des valeurs peut changer de temps en temps.

également une tâche commune consiste à interroger l'ensemble de la valeur autorisée, par exemple pour remplir un champ de formulaire dans l'interface utilisateur. Lorsque les valeurs sont autorisées dans une table de consultation, cela est beaucoup plus facile que quand ils sont définis dans une liste de valeurs littérales dans une contrainte CHECK ou définition ENUM.


Re commentaire "comment faire exactement recherche sans id"

CREATE TABLE LookupStrings (
  string VARCHAR(20) PRIMARY KEY
);

CREATE TABLE MainTable (
  main_id INT PRIMARY KEY,
  string VARCHAR(20) NOT NULL,
  FOREIGN KEY (string) REFERENCES LookupStrings (string)
);

Maintenant, vous pouvez être assuré qu'aucune valeur en MainTable.string est invalide, car l'intégrité référentielle empêche que. Mais vous ne devez pas se joindre à la table de LookupStrings pour obtenir la chaîne, lorsque vous interrogez MainTable:

SELECT main_id, string FROM MainTable;

Voir? Pas rejoindre! Mais vous obtenez la valeur de chaîne.


Re commentaires sur plusieurs colonnes de clé étrangère:

Vous pouvez avoir deux clés étrangères individuels, chacun pointant potentiellement à différentes lignes de la table de consultation. La colonne de clé étrangère ne doit pas être le même nom que la colonne dans la table référencée.

Mon exemple courant est une base de données de suivi de bogues, où un bug a été signalé par un utilisateur, mais assigné à fixer par un autre utilisateur. Les deux reported_by et assigned_to sont les clés étrangères faisant référence à la table de Accounts.

CREATE TABLE Bugs (
  bug_id INT PRIMARY KEY,
  reported_by INT NOT NULL,
  assigned_to INT,
  FOREIGN KEY (reported_by) REFERENCES Accounts (account_id),
  FOREIGN KEY (assigned_to) REFERENCES Accounts (account_id)
);

Dans Oracle, SQL Server et PostgreSQL, utilisez la contrainte de CHECK.

CREATE TABLE mytable (myfield INT VARCHAR(50) CHECK (myfield IN ('first', 'second', 'third'))

Dans MySQL, utilisez le type de données ENUM:

CREATE TABLE mytable (myfield ENUM ('first', 'second', 'third'))
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top