La conception orientée objet encourage l'utilisation d'objets immuables pour améliorer la sécurité des threads et la performance. Je me demande si cela porte sur des bases de données relationnelles. P>
Option 1 Strong>: Chaque fois qu'un employé change de sociétés, insérez un nouvel employé [nom, une entreprise]. L'application est chargée de sauter des lignes plus anciennes (qui sont éliminées dans un fil de fond au fil du temps).
Option 2 Strong>: Chaque fois qu'un employé modifie les entreprises, mettez à jour la ligne existante. P>
L'option 1 me rappelle des objets immuables en ce que c'est le fil-coffre-fort (pas besoin de serrures). D'autre part, chaque fois que l'employé change de sociétés, je dois cloner tous les objets associés et les signaler au nouvel enregistrement. En outre, il n'est pas clair comment prévenir les effectifs d'être créés par erreur. P>
L'option 2 facilite la prévention des employés en double, mais a la possibilité de renvoyer des associations potentiellement incohérentes dans l'isolement de la transaction LIVE_COMMIS. P>
5 Réponses :
La différence de base est la suivante: p>
Si vous insérez une nouvelle ligne pour chaque changement, etc. "Désactiver" l'ancienne ligne en définissant une date "validant", alors vous avez des antécédents de ce que les changements où, au fil du temps, vous entrez dans la zone d'une base de données "temporelle" p> li>
Si vous continuez à mettre à jour la même ligne encore et encore, vous avez toujours l'état actuel - mais pas l'histoire. P> li> ul>
Donc, je suppose que c'est vraiment la grande question: faites-vous
C'est un bon point. Les systèmes audibles nécessitent une histoire immuable. Cela étant dit, ne pouviez-vous pas séparer le système en données en direct et à des données historiques? Les données en direct seront à jour en place (simplifiant l'intégrité-vérification) et insérer une copie dans la table d'audit.
Si vous utilisez souvent des informations temporelles et revenez à temps, vous voudrez peut-être envisager l'une des nouvelles bases de données de documents (du monde de la NOSQL). Certaines de celles prennent explicitement soutenir des conceptions d'insertion d'insertion uniquement en optimisant leur stockage de données pour exactement ce cas d'utilisation. Cela rend l'insertion beaucoup i> plus rapide et peut améliorer les rapports. Les DBs relationnels communs sont meilleurs pour changer les données existantes et se lent de plus en plus lents avec de grands ensembles de données (ce qui est principalement inutile lorsque cet ensemble de données contient simplement des données mortes / obsolètes).
Je pense que je viens de répéter votre réponse Marc_s. Aucun plagarisme prévu.
Je pose cela dans l'espoir que cela aide les autres à l'avenir. J'ai personnellement gaspillé d'innombrables jours qui descendent ce chemin (faux). P>
Les objets immuables sont destinés à des types de valeur (pensez entier, un horodatage, une lecture de la température, etc.). Ce sont des types qui ne changeront jamais. Au moment où vous commencez à parler de modification des valeurs d'objets immuables, c'est une indication assez forte que vous descendez du mauvais chemin. Lorsque vous utilisez d'authentiques objets immuables, vous ne devez jamais avoir à mettre à jour les références d'objets associés. P>
Donc, la bonne réponse, que ce soit pour la programmation orientée objet ou la conception de la base de données, est de mettre à jour des objets mutables en place. P>
Cela vous permet de profiter du meilleur des deux mondes. P>
Il est facile de couper une piste d'audit immuable, de manière appropriée des valeurs de «immuables». Mais sérieusement, il est i> bien de stocker des données d'audit dans une table différente. Les données dans la table d'audit ne concerne pas l'entité de la table d'origine; C'est à propos de la rangée.
Ce ne sont pas des options. Ce sont des choses complètement différentes, et ils nécessitent des tables complètement différentes. La partie douloureuse est que les données des tables pourraient ressembler exactement à la même chose. Voici comment les distinguer.
Chaque table dans une base de données relationnelle comporte un et un seul prédicat. Le prédicat détermine ce que signifient les rangées du tableau. Donc une table dont les données ressemblent à ceci p> peut signifier p> une telle table exclut des consultants, car ils " n'est pas des employés. (Dans les Etats-Unis, ils ne sont pas, de toute façon.) P> mais cela pourrait signifier p> et cette table permettrait également P> Person named NAME once was an employee of company COMPANY.
Je ne suis pas d'accord. L'option 1 peut être utilisée pour modéliser la société actuelle d'un employé si le code de l'application est chargé de ne utiliser que le dernier enregistrement (les enregistrements plus anciens sont coupés au fil du temps). Ce n'est peut-être pas la chose la plus intuitive au monde, mais il n'y a rien de tecourci techniquement avec ça.
@Gili: Non, ça ne peut pas. Une table conçue pour implémenter les contraintes de cas d'utilisation ne vous laissera pas insérer plus d'une ligne pour chaque personne. (Cela violerait le prédicat.) Ni SQL ni relation relationnelle ne soutiennent aucun concept de "la dernière ligne" en l'absence d'une colonne pour laquelle "dernier" est significatif. Le cas d'utilisation n'a clairement pas une telle colonne. Et ce n'est pas un cas de "Le" code d'application étant chargé de faire quelque chose; C'est un cas de souvenir d'écrire chaque i> du code de l'application pour faire exactement la même chose - une pratique de développement connue pour échouer plus souvent que cela ne réussit.
Ma faute. Je voulais dire que si vous aviez Employee [ID, nom, société], vous pouvez insérer plusieurs entrées pour le même nom d'employé et que l'application n'utilise que le dernier. "ID" est défini comme une colonne d'incrémentation automatique qui identifierait la "dernière" ligne. Vous avez raison sur une chose si: il pourrait y avoir plusieurs applications pour accéder à la même base de données.
@Gili: Et si vous l'avez fait, que feriez-vous des clés étrangères d'autres tables? Les clés étrangères diraient-elles à l'ID "Old". Il y a une raison pour que les concepteurs de base de données n'acceptent jamais quelque chose comme vous proposez. Ce n'est pas parce que nous sommes difficiles ou stupides.
@CATCALL, c'est pourquoi ma question précisait que vous devriez cloner tous les objets associés (et pointez les nouvelles clés étrangères dans les nouveaux enregistrements). Je n'ai jamais voulu impliquer que l'option 1 est géniale, mais elle a ses utilisations. Que pensez-vous de la réponse que j'ai posté à
"'ID' est défini comme une colonne d'incrémentation automatique qui identifierait la" dernière "ligne". Ce n'est pas comme ça qu'ils travaillent. Les transactions comportant un numéro d'identification de numéro inférieur ne sont pas garanties pour commettre une transaction ayant un numéro d'identification plus élevé. Il y a des moyens autour de cela, mais aucun d'entre eux ne vous soulage de la responsabilité de définir le prédicat de la table et qu'aucun d'entre eux ne laissait une table n'a plus d'un prédicat.
SELECT PersonID FROM tblCompany_Employee WHERE PersonID = @PersonID AND CompanyID = @CompanyID AND EndDate IS Null
En général, l'entreposage de données a tendance à suivre le modèle "insert uniquement". La raison en est que des lignes obsolètes dans les tables de diomentes sont encore nécessaires pour placer des faits anciens dans le contexte qui existait quand ils étaient de nouveaux faits. P>
Exemple: La Pennsylvanie faisait partie de la région des ventes du nord-est jusqu'au 1er janvier, date à laquelle il est devenu une partie de la région de vente du Moyen-Atlantique. Une vente qui a été faite en décembre dernier doit renvoyer à une rangée dans la table de dimension géographique qui la place dans la région du nord-est. Une mise à jour à la place de la table de dimension «State» invaliderait cet ancien fait. P>
La tendance des bases de données OLTP consiste à effectuer des mises à jour en place et à garder une trace de ce qui est actuellement le cas. Cependant, cela peut entraîner une copie des données dans des lignes de transaction. Par exemple, la ligne de détail de facture dans un système de commande d'achat peut contenir le prix de l'article commandé, copié de la ligne de la table des produits. De cette façon, si le prix est mis à jour dans la table des produits, le prix affectant cette facture ne doit pas être encombré. P>