J'ai une colonne de texte qui devrait avoir seulement 1 des 3 chaînes possibles. Pour mettre une contrainte dessus, je devrais référencer une autre table. Puis-je à la place mettre les valeurs de la contrainte directement sur la colonne sans faire référence à une autre table?Puis-je mettre une contrainte sur une colonne sans faire référence à une autre table?
Répondre
Si c'est SQL Server, Oracle, ou PostgreSQL, oui, vous pouvez utiliser un check constraint
.
Si c'est MySQL, check constraint
sont reconnus mais non appliqués. 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, ceci est généralement mal vu, car il n'est définitivement pas facile à maintenir. Il est préférable de créer une table de recherche et d'assurer l'intégrité référentielle à travers cela.
"Cependant, ceci est généralement mal vu, car il n'est certainement pas optimisé." - Avez-vous une chance de fournir un lien vers une explication? Je suppose que vous voulez dire que les contraintes affectent la performance des mises à jour/insertions - et une table de recherche est certainement une meilleure solution pour la question originale - mais j'aimerais en voir plus sur l'impact sur les performances. – Mayo
'@ mmayo': une contrainte' CHECK' est plus difficile à maintenir qu'une table de recherche 'FOIREGN KEY', mais' CHECK' est plus efficace qu'une table de recherche dans tous les systèmes mais 'MySQL' (qui ne supporte pas' CHECK' contraintes). Dans 'MySQL', une table de recherche peut être plus efficace qu'une condition' IN' avec une analyse de plage sur une longue liste de prédicats. Voir cet article dans mon blog pour le détail des performances: http://explainextended.com/2009/08/18/passing-parameters-in-mysql-in-list-vs-temporary-table/ – Quassnoi
'@ Eric': pour votre exemple (avec seulement trois valeurs possibles) une table de consultation sera moins efficace même dans 'MySQL'. Il ne paie que pour les très longues listes qui doivent être conservées dans une table de recherche pour des raisons de maintenabilité et non de performance. – Quassnoi
Dans Oracle
, SQL Server
et PostgreSQL
, utilisez la contrainte CHECK
.
CREATE TABLE mytable (myfield INT VARCHAR(50) CHECK (myfield IN ('first', 'second', 'third'))
En MySQL
, utilisez ENUM
type de données:
CREATE TABLE mytable (myfield ENUM ('first', 'second', 'third'))
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 souhaitée.
Je ne recommande pas forcément un déclencheur en tant que bonne solution, je signale simplement une autre option qui répond à vos critères de ne pas référencer une table de recherche.
Mon habitude est de définir des tables de recherche au lieu d'utiliser des contraintes ou des déclencheurs, quand la règle consiste simplement à restreindre une colonne à un ensemble fini de valeurs. L'impact sur les performances de la vérification par rapport à une table de recherche n'est pas pire que l'utilisation de contraintes ou de déclencheurs CHECK, et il est beaucoup plus facile à gérer lorsque l'ensemble de valeurs peut changer de temps en temps.
Une autre tâche courante consiste à interroger l'ensemble de valeurs autorisées, par exemple pour renseigner un champ de formulaire dans l'interface utilisateur. Lorsque les valeurs autorisées sont dans une table de recherche, cela est beaucoup plus facile que lorsqu'elles sont définies dans une liste de valeurs littérales dans une contrainte CHECK ou dans une 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 n'avez pas à se joindre à la table LookupStrings
pour obtenir la chaîne, lorsque vous interrogez MainTable
:
SELECT main_id, string FROM MainTable;
Voir? Pas de jointure! 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 n'a pas besoin d'être nommée la même que la colonne dans la table référencée.
Mon exemple courant est une base de données de suivi de bogues, dans laquelle un bogue a été signalé par un utilisateur, mais assigné à un utilisateur différent. Les deux reported_by
et assigned_to
sont des clés étrangères faisant référence à la table 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)
);
une note, avec 2 clés étrangères, le serveur sql n'autorise pas les changements en cascade dans les deux colonnes. correct? – zsharp
Non, je ne crois pas qu'une telle limitation existe. –
- 1. Comment convertir une contrainte ForeignKey sur une colonne en une autre table avec des clés primaires à plusieurs colonnes?
- 2. PostgreSQL: contrainte, Insérer une valeur dans la colonne uniquement si elle existe dans une autre table
- 3. Joindre plusieurs colonnes dans une table à une seule colonne dans une autre table
- 4. copier une colonne d'identité dans une autre table
- 5. sql server 2005: comment mettre une contrainte non nulle sur une colonne en fonction de la valeur dans une autre colonne?
- 6. Contrainte SQL Server 2000 impliquant une colonne sur une table différente
- 7. Django - comment faire référence à une autre application
- 8. MySQL mettre à jour une ligne quand une autre change
- 9. Mettre à jour la colonne d'une autre table - mySQL 3.5.2
- 10. Comment obtenir une référence à une ligne de table avec une valeur spécifique dans jQuery
- 11. Désactiver la contrainte de clé étrangère sur une table?
- 12. Insérer une partie d'une table dans une autre table
- 13. Mettre à jour une colonne NText
- 14. lignes SQL sélection où une valeur de colonne est commune à une autre colonne de critères
- 15. Mettre à jour une colonne d'horodatage
- 16. Comment puis-je auto calculer une colonne dans une table sans utiliser une vue
- 17. mise à jour SQL une table d'une autre table
- 18. Comment mettre à jour une table automatiquement?
- 19. Comment obtenir une référence à une autre classe correctement?
- 20. Comment mettre à jour une table relationnelle?
- 21. Convertir les données dans une table à une autre vue
- 22. Référence SQL Server une colonne calculée
- 23. Puis-je mettre une contrainte sur une table de serveur SQL pour ne pas autoriser la chaîne vide?
- 24. SSIS - Exécution d'une recherche sur une autre table pour obtenir la colonne correspondante
- 25. Comment insérer une plage de clés dans une autre colonne
- 26. NHibernate cartographie une table de référence
- 27. Est-il possible de définir une contrainte unique en tant que clé étrangère dans une autre table?
- 28. Puis-je ajouter une contrainte UNIQUE à une table PostgreSQL, après qu'elle a déjà été créée?
- 29. entity-framework une table sans clé unique
- 30. SQL: Insérer tous les enregistrements d'une table vers une autre table sans les colonnes spécifiques
Publiez quelle plateforme de base de données vous utilisez. Regardez toutes ces personnes pauvres qui répondent à vos questions avec plusieurs plates-formes, en sortant de leur manière de vous s'il vous plaît. –
regardez l'étiquette qui dit sql – zsharp
et était aussi en titre mais Bill l'a édité – zsharp