Imaginez la base de données suivante: p>
Table 'Sociétés' a des champs ID, Nom et Flagship_Product_ID. Table 'Produits' a des champs ID, Nom et Company_id. P>
Une entreprise doit avoir un produit phare (relation 1: 1) et tous les produits ont une entreprise (1: N relation). P>
Lorsque vous utilisez un moteur de stockage tel que le myisme, il ne devrait y avoir aucun problème avec le scénario ci-dessus, mais lors de l'utilisation d'un moteur tel que InnoDB, des problèmes résultent lors de l'insertion de nouvelles données. P>
Quelle est une bonne solution, sauf indication d'une relation nulle pour l'insert initial? p>
Résumer, une entreprise
7 Réponses :
Je ne connais pas ce moteur de base de données, mais recherchez un moyen de suspendre temporairement les contrôles de cohérence des données ou l'intégrité référentielle lors de vos opérations d'insertion atomique et de mise à jour. P>
Sur MySQL, c'est SET FORET_KEY_CHECKSS = 0 code>, mais est-ce le seul moyen?
Je suis sûr que c'est la route, si vous vous tenez à cette conception. Si vous ne l'avez fait que pendant la durée de l'opération, pourquoi serait-ce indésirable? Je pense que je sais ce qui vous dérange - vous voulez que ce soit plus propre. Malheureusement, je pense que ces bases de données relationnelles ne sont pas bonnes pour exprimer ce type de relation.
Certaines choses doivent être appliquées dans la couche d'application. :-)
Je pense que c'est mon seul choix alors, j'ai besoin de faire respecter cette relation et je ne trouve aucune autre solution. J'ai choisi celui-ci parce que c'est le seul qui me permet de conserver une relation sain de "drapeaux" où l'erreur de programme peut casser des choses.
Il n'y a rien d'esprit d'esprit ... en règle générale, si vous devez suspendre les chèques, votre modèle est cassé. Je ne dis pas que cela ne fonctionnera pas, mais une fois que vous avez suspendu le chèque de l'insert, rien ne forçant ce champ à régler à quoi que ce soit ... Vous avez les mêmes problèmes de programme que vous avez si vous définissez un drapeau dans votre Table de produit.
Vous restaurez les chèques à la fin de l'opération, échec si les données ne sont finalement cohérentes - et d'autres opérations de ce type continuent d'être cohérentes individuellement. Devrait être bien. RDBMS est un outil puissant, mais il n'aura pas de primitif propre pour chaque situation de niveau d'application. Vous pourriez simplement considérer cela une optimisation des sortes, enfoncées du niveau d'application.
C'est l'une de ces choses qui sont mieux faites dans le code de la demande. C'est un système très étrange qui configurerait la société et les produits dans une seule transaction! Le problème est que vous configurez une nouvelle entreprise et suspendez le chèque pour le faire. Ensuite, vous devez entrer et créer les produits immédiatement, avant de pouvoir associer le "produit phare". Tout le temps, vous devez laisser les règles dans un état suspendu.
Je suis d'accord, dans ce scénario, suspendre les chèques est une mauvaise idée. La suspension de l'intégrité ne doit être effectuée que pendant la durée de la transaction - non laissée ouverte. Dans ce cas, l'autorisation de NULLS serait beaucoup mieux.
C'est la pire chose à faire.
Pourquoi ne pas mettre un champ de produit phare dans la table des produits en tant que booléen ... vous pouvez indexer cela et comprendre et avoir une jolie recherche rapide p>
Un index n'a aucun impact sur les règles d'entreprise - qui ont voté pour cela ?!
Vous allez devoir autoriser des nulls dans le produit phare_product ou reconsidérer comment vous modélisez cette situation. Envisager de mettre le produit phare comme un champ booléen sur le produit à la place. Ensuite, vous n'avez pas de dépendance circulaire. Ou avoir un champ de type_TYPE sur le produit pouvant avoir des valeurs telles que phares ou normales ou obsolètes ou autre. Bien sûr, vous devez faire respecter cela, mais dans le passé, j'ai trouvé une solution plus propre à ce type de problème. P>
Vous pouvez facilement prendre cette étape plus loin et avoir une table de produit_attributes qui répertorie les attributs associés à un produit - dont l'un pourrait être «phare». Cela permet de multiples attributs si nécessaire.
Mais alors cela signifie qu'il pourrait y avoir plusieurs produits phares pour une entreprise, qui n'est pas souhaité.
Comme je l'ai dit, il doit être exécuté.
Comment diriez-vous-tu? Les contraintes de contrôle ne fonctionneront ni une clé unique.
Vous l'exécutez au niveau de l'application (ma préférence) ou avec des déclencheurs sur la table.
Mais c'est une relation simple pour modéliser - vérifier ma réponse pour un exemple. Le niveau d'application peut avoir des problèmes s'il s'agit d'une application de bureau.
@Rexem: C'est une solution valide mais comme indiqué qui n'applique pas qu'une entreprise a un produit phare, seulement qu'elle n'a pas de 2+.
@cletus: C'est une hypothèse incorrecte. La relation n'est que celle-là exister pour une entreprise lors de la définie.
Sinon, le premier produit ajouté pour une entreprise devra être connecté en tant que phare puis mis à jour lorsque le phare a été ajouté.
@Rexem: Vous pouvez appliquer avec une clé unique sur les champs Société_id et Flagship_Product. Mais je suis d'accord avec le clétus qu'il serait mieux appliqué au niveau de l'application.
@Jeff: Vous ne pouvez pas mettre une clé unique sur le Company_id code> et
phare code> - alors vous avez besoin de valeurs phares différentes pour chaque société_id.
Je recommande d'utiliser le modèle de données suivant: p>
entreprises p>
Produits P>
flagship_products p>
Création d'une colonne phare dans la table code> code> ne garantira qu'un seul produit est le produit phare de la société donnée car: P>
Ce modèle nécessite unique (société_id, produit_id) code> sur
flagship_products code>, non? Donc, c'est fondamentalement une table de pivot 1: 1 (bizarre ...).
@strager: parce que le pc est code> société_id code>, vous ne pouvez avoir une seule entrée pour une entreprise - il n'y a pas besoin d'une clé unique sur produit_id code>
Comment puis-je Appliquer B> qu'une entreprise a un produit phare, alors?
@rexem, ah, vrai. @Liranuna, aucune idée. Cette solution n'applique qu'un ou aucun. Hmm...
La relation serait appliquée lorsqu'un utilisateur tente d'ajouter un produit indiqué comme le produit phare quand on existe déjà pour cette entreprise. La clé principale arrêterait les doublons de la valeur code> company_id code>.
@Remex, mais que l'ajout n'est pas appliquée. Vous pourriez avoir une entreprise sans produit phare. Ce n'est pas ce que veut @liranuna.
Et il vaut mieux assumer que tous les produits sont le système phare, sauf indication contraire? C'est ce que la valeur de la valeur défaillante fera, sans la capacité d'assurer une existence. Qu'en est-il des entreprises qui n'ont pas de produits?
Je m'attendrais à ce que le produit phare soit exposé / surligné dans l'application si elle est si importante.
C'est toujours une relation circulaire ... Vous venez d'ajouter une autre table au mélange.
Le tableau "Extra" applique la règle commerciale selon laquelle il ne peut y avoir qu'un seul produit phare pour une entreprise tout en permettant une entreprise d'être ajoutée sans produit existant. En venant de l'affiche qui a recommandé un index, pourquoi vous sentez-vous la nécessité de commenter quelque chose que vous savez rien?
@strager: En supposant que vous signiez société.flagship_product_id code>, oui - cette colonne devrait autoriser
null code> lors de la création d'une entreprise compte tenu des règles de gestion. Mais ce serait mieux que d'avoir une colonne indicatrice dans la table Code> Produits Code> - En plus de la gaspillage, il n'y a aucun moyen d'appliquer la règle de produit phare.
Je suis tout à fait d'accord que cela oblige la relation 1-1, mais cela n'exige pas qu'il y ait un produit phare en premier lieu, ce qui doit être fait au niveau de l'application. Peu importe ce que vous faites, vous ne pouvez pas vous éloigner de la vérification de l'application!
N'AVEZ JAMAIS SAI N'AVAI N'A PAS - Avoir toute la validation que vous souhaitez dans l'application, mais le modèle de données ne doit pas compter sur la validation de l'application pour appliquer l'intégrité des données.
Les seuls produits suffisamment puissants et suffisamment puissants pour faire face à de telles situations sont correctement des systèmes qui embrassent / implémentent le concept de mission multiple. P>
Il n'y a pas un seul système SQL joue dans cette ligue. P>
Modifier P>
Les systèmes SQL ont une vérification de contrainte différée, mais en utilisant cela peut devenir désordonné. P>
Voici un aperçu d'un travail possible. Je ne sais pas à quelle hauteur de l'échelle de Kudge que cela convient, mais c'est là-haut. P>
Par la suite, chaque fois qu'un client ou un produit est créé, si le produit / entreprise référencée correctement n'a pas encore été créé, vous initialisez le nouvel élément à pointer vers le PLACHOLDER DUMMY. Ensuite, vous entrez cet élément et vous avez terminé en mettant à jour la première entrée. P>
La hausse est, vous avez une intégrité référentielle absolue une fois que votre routine d'initialisation de la base de données est terminée - et vous ne courez qu'une fois sous lesquelles des circonstances contrôlées très em> em>, regardez-la de près et assurez-vous que cela ne le fait pas. t échoue! Le non-inconvénient est que vous avez maintenant un article "supplémentaire" de chaque table encombrant votre système. P>
Est-ce que c'est mieux que de laisser NULLS - NULL Être votre espace réservé réservé invisible?
Référencement d'une ligne mannequin ou d'espace réservé est une alternative standard (the?) À avoir une référence de clé étrangère nulle. C'est comme "null" = nous ne savons pas ce que c'est et "Placholder" = Nous savons que nous n'avons pas les données, et nous gérons de manière proactive la situation avec des données délibérément inscrites. L'inconvénient est que vous devez gérer / code délibérément pour l'espace réservé ... mais vous devriez alors faire la même chose avec NULLS aussi, alors pourquoi ne pas le rendre un peu plus évident ce qui se passe?
Vous aurez besoin de casser le cycle par veuillez s'il vous plaît google pour "initialement différé différé". p>
(pas sûr si InnoDB soutient cela) p>
J'ai un problème très similaire bien que Innodb n'est pas un facteur. La dépendance circulaire dans le schéma est le problème.