6
votes

Créez une clé primaire sur mesure "auto-incrément"?

J'ai un ensemble de tables parent-enfant (1 à de nombreuses relations). Je construis des tables et j'ai des doutes sur l'utilisation de PKS et de l'incrémentation automatique.

La table parent comporte un autonumber PK (est utilisé pour stocker l'en-tête de vente de vente). Un enregistrement ici signifie sur le ticket.

La table enfant est utilisée pour stocker des détails de billet. Un disque ici est un élément de ligne dans le billet (E.g. Coke, Mars Bar, etc.)

Je comprends que PK pour la table enfant doit avoir 2 champs:

  1. PK de Tables parent
  2. Un numéro qui rend l'élément de ligne unique dans ce billet

    si j'utilise identité , il ne "redémarrera" ne "redémarrer" après les modifications de PK de Parent.

    Je vais le montrer avec un exemple:

    a) Qu'est-ce que SQL fait xxx

    b) ce que je veux atteindre xxx

    Remarque: COL1 est tiré de la table des parents; Col2 réinitialise après le changement de Col1; Col1 composé avec Col2 est unique.

    est-ce que SQL Server implémente cette utilisation de clés? Ou devrais-je avoir besoin de le coder?


2 commentaires

Vous auriez besoin de le coder, il n'y a pas de raccourci à cela.


Comme d'autres l'ont dit, il n'y a pas de mise en œuvre directe pour cela. Vous devrez utiliser une table de pont ou écrire du code pour appliquer l'exigence. Vous pourriez envisager: vous n'avez pas besoin de stocker les données comme celle-ci. Si tout ce dont vous avez besoin est Numéros d'article sur un ticket, il pourrait être résolu comme un problème d'affichage plutôt qu'un problème de stockage. Regardez les fonctions fenêtres dans SQL comme: Row_Number () Over (Partition par Col1 Ordre par Col1, Col2)


3 Réponses :


1
votes

Vous n'avez pas de relation unique. Vous avez une relation nombreuses à plusieurs. Un parent peut avoir beaucoup d'articles. Un coke peut appartenir à plus d'un parent.

Vous voulez trois tables. La table intermédiaire est parfois appelée table de jonction.

http://fr.wikipedia.org/wiki/junction_table

Remarque: Dans l'article Wiki, ils ne montrent que deux colonnes dans la table de jonction, je pense que la meilleure pratique est que cette table a également un champ auto-incrémentant unique.

REMARQUE: Les deux champs de jonction sont généralement fabriqués un indice unique.


2 commentaires

Une table de jonction fait pas besoin d'une colonne d'auto-incrémentation supplémentaire. C'est totalement inutile car il a déjà une clé primaire.


Je n'ai pas dit que les tables de jonction ont besoin d'une colonne d'incrément automatique. J'ai dit que c'est bien d'en avoir un. En fait, de nombreux contrôles de liaison automatique de gui-auto nécessitent un. Et, il est beaucoup plus facile de supprimer / mettre à jour un enregistrement à l'aide d'un seul champ que de toujours spécifier les deux champs. Dans certains magasins, c'est une pratique obligatoire.



0
votes

Vous devrez coder la logique pour cela vous-même. Vous pouvez faciliter la tâche en mettant la tâche en la mettant en œuvre par des déclencheurs et à l'aide des fonctions de fenêtre (Row_Number () sur (partition par parent_id commander par ...).

Vous pouvez également laisser la clé primaire simplement être une colonne d'identité (le parent_id ne a doit faire partie de la PK) et avoir une colonne "Séquence_num" pour garder une trace de l'int. que vous souhaitez réinitialiser avec chaque parent_id. Vous pouvez même le faire et toujours définir un index en cluster sur les cols parent_id / séquence_num.

IMHO La 2e option est meilleure car elle permet une plus grande flexibilité sans aucun inconvénient majeur. Il facilite également la fonction de fenêtre d'écrire, car vous pouvez commander par la clé de substitution (la colonne d'identité) pour préserver l'ordre d'insertion lors de la régénération de la séquence_num. Dans les deux cas, vous devez gérer vous-même votre séquençage de votre colonne "séquenec_num".


0 commentaires

3
votes

Tout comme exemple:

create trigger dbo.trInsertOrderPos on dbo.tOrderPos instead of insert
as begin
    insert into dbo.tOrderPos
            (OrderID, OrderPosNo, ProductID)
    select  OrderID,
            OrderPosNo =
            isnull( (select max(opo.OrderPosNo)
                    from    dbo.tOrderPos opo
                    where   opo.OrderID = i.OrderID), 0) +
            row_number() over (partition by OrderID order by (select 1)),
            ProductID
    from    inserted i;
end;


0 commentaires