7
votes

Les projets d'enregistrements doivent-ils être conservés dans une table séparée?

Nous construisons un système Web simple, dans lequel quelqu'un ajoute un enregistrement, une page CMS, par exemple, qui est approuvée par une personne responsable avant d'être affichée sur le site Web.

Si l'auteur décide ensuite de modifier cette page plus tard, nous souhaitons créer un brouillon basé sur la copie en direct, sur approbation, il remplacera l'ancienne page en direct.

Nous avons pensé à faire une version complète de la version, mais croyons que nous pouvons garder cela plus simple en ayant simplement 1. Juste un brouillon, 2. Juste un vivant, ou 3. un brouillon et un vivant.

Cette fonctionnalité est requise sur plusieurs «choses» non seulement des pages.

Enfin la question: Pensez-vous qu'il serait préférable de stocker ces deux enregistrements dans la même table, ou une table miroir serait-elle meilleure?

Je suppose que cela dépend probablement mais je n'aime pas l'idéal d'avoir deux tables avec la même structure. Est le compromis pour des opérations légèrement plus lentes (comme nous devrons interroger les brouillons tout le temps lors de l'affichage des données) en valant la peine?


3 commentaires

"Opérations légèrement plus lentes" Avez-vous mesuré? Est-ce un fait? Ou supposez-vous que cela serait plus lent?


Comment peut-il être un fait quand je ne l'ai même pas encore écrit? De toute évidence, je suppose que l'ajout d'une clause où il est opposé à simplement choisir tous les enregistrements d'une table en direct sera plus lent, mais je suis très ouvert pour apprendre pourquoi je me trompe.


Si vous ne l'avez pas écrit, vous devez construire deux solutions de pointe et mesurer la différence. En supposant que c'est mauvais. La mesure est bonne.


4 Réponses :


10
votes

déplacer des trucs de table à table quand il y a un changement d'état est une mauvaise idée.

Lorsque vous souhaitez ajouter des états supplémentaires au workflow, vous devez ajouter plus de tables.

C'est juste un changement d'état - c'est ce que les bases de données relationnelles sont optimisées pour.

une table, plusieurs états sont l'approche standard.

Si vous constatez que les choses sont horriblement lentes - et vous pouvez prouver que la requête basée sur l'Etat est toute la cause - vous pouvez recourir à une "vues matérialisée" ou à une technologie similaire où le changement d'état (et le déplacement résultant) est géré par le SGBDM.

Table-Per-State est une mauvaise idée.

  1. Vous ne pouvez pas facilement ajouter des états. Vous devez également ajouter des tables, ce qui le rend douloureux. En outre, vous devez mettre à jour le code avec le ou les nouveaux noms de table pour refléter le nouveau flux de travail.

    Si un état n'est qu'une colonne, l'ajout de nouveaux états ajoute de nouvelles valeurs et de nouvelles instructions IF dans le code. Les modifications de l'état ne sont que des mises à jour et non "Supprimer-insert".

    Les données durent éternellement, les flux de travail viennent aller à chaque fois qu'un utilisateur a une idée intelligente. Ne les punissez pas pour vouloir changer le flux de travail.

  2. Vous ne pouvez pas facilement avoir des sous-états. De nombreuses machines d'état sont en fait multiples, imbriquées, machines d'état. L'ajout d'un sous-état avec une table-Per-Etat crée encore plus de tables avec des règles encore plus.

    Si un état n'est qu'une colonne, un subssets imbriqués est juste une autre colonne avec de nouvelles déclarations IF dans le code. Les modifications de l'état ne sont que des mises à jour et non "Supprimer-insert".

  3. Vous ne pouvez pas facilement avoir des machines d'état parallèles. Plusieurs fois, il existe de nombreux changements de code d'état parallèle. Parfois, il existe des flux de travail manuels (approbations) et des odflows automatisés (archivage, copie sur l'entrepôt de données, etc.) avec des machines d'état de table et parallèles, il n'y a aucun moyen de le mettre en place de manière rationnelle

    Si chaque état n'est qu'une colonne, des machines à états parallèles ne sont que des mises à jour parallèles.


4 commentaires

Dans l'ensemble, je suis d'accord avec ce que vous dites, mais vous savez bien que ce n'est pas un seul disque qui traverse un ensemble d'États? Ce sera initialement, mais un projet devra ensuite exister avec l'enregistrement live connexe et le remplacer possibles ultérieurement après l'approbation.


@rsdBrown: "Ajoute un enregistrement". Cela me semble singulier. Veuillez mettre à jour la question si ce n'est pas un enregistrement. Ce qui est important, c'est que la mise à jour de plusieurs enregistrements ou la mise à jour d'un seul enregistrement n'a pas d'importance. Table-Per-State est une mauvaise conception et s'aggrave rapidement lorsque vous essayez d'ajouter des états. L'état n'est qu'un code d'état de la ligne.


Regardez, nous sommes d'accord avec les deux tables étant un mauvais design, je me suis même allongé à mes pensées sur ma question! La raison pour laquelle j'ai posé une question était parce que j'ai vu comment d'autres ont mis en œuvre cela dans des plug-ins de Rails tels que ACTS_AS_VERSIONED et HAS_DRAFT. Je ne pense pas que vous comprenez ma question et c'est probablement ma part. Cependant, d'autres semblent saisir l'idée et je crois que la question est assez claire. Merci pour votre participation. Le vôtre, les autres et mes propres pensées ont aidé à confirmer que je n'aurai pas deux tables.


"Je ne pense pas que tu comprends ma question". Ce commentaire n'a pas clarifié votre question, vous n'avez pas modifié votre question pour clarifier. En disant simplement que je n'ai pas compris ne semble pas la clarifier non plus. N'hésitez pas à mettre à jour votre question pour le rendre plus clair.



5
votes

non. Un type d'entité, une table.

raisons de reconsidérer:

  1. Les enregistrements judiciaires dépassent des enregistrements en direct par un facteur de milliers à un.

  2. Les conditions de sécurité exigent que certains utilisateurs qui accédent à la base de données aient directement certains droits sur des dossiers de brouillon ou de réveil au niveau de la subvention / révocation, mais pas sur l'autre type d'enregistrement.

    Une deuxième conception à considérer serait une table pour les articles et une deuxième table pour les liveItems. La deuxième table ne contient que les identifiants des articles qui vivent. De cette façon, vous maintenez votre conception de table unique, mais vous pouvez trouver les liveitems en rejoignant votre table à une colonne à la table principale.


0 commentaires

2
votes

convenu avec tous les commentaires donnés ci-dessus: une seule table.
Avec le SCOPES , vous pouvez facilement obtenir uniquement les messages publiés ou les brouillons.

Je ne le recommanderais pas.
Mais si vous souhaitez vraiment avoir deux modèles différents pour les brouillons et les entrées publiées, il y a une autre solution cependant:
STI . P>

Vous auriez deux modèles: p> xxx pré> tout Le projet d'objet est extrait de la table postale.
Le paramètre type en fait un poste ou un brouillon. P>

Chaque fois que vous souhaitez publier un message, vous devez alors faire: P>

@draft = Draft.first
@draft[:type] = 'Post'


1 commentaires

Sti était autre chose que j'avais envisagé d'avoir une colonne de statut avec des étanches est presque la même que d'avoir une colonne de type. Diriez-vous que les scopes / statut serait mieux alors? J'aime l'idée de STI comme alors les contrôleurs seront comme LivePost.all et DraftPost.All



0
votes

Je viens de faire un gemme pour un tel cas d'utilisation. Il stocke des brouillons dans une table séparée: https://github.com/ledermann/drafting


0 commentaires