web-dev-qa-db-fra.com

Normaliser une table avec un champ qui identifie généralement une rangée de manière générale, mais est parfois nulle

pardonnez-moi si cela a été demandé et répondit auparavant.

Je tire un schéma pour un système de gestion des stocks, à mettre en œuvre dans PostgreSQL. Tous nos produits et services ont une SKU. la plupart de nos produits proviennent du fabricant ou du distributeur avec un "numéro d'article" distinct (que ce soit le numéro de catalogue du distributeur, le numéro de modèle du fabricant, quoi que ce soit). Cependant, tous n'avaient pas un tel nombre. Nous avons de petites assemblées que nous faisons en interne qui, généralement, n'ont pas de numéros d'article. Nos services n'ont pas de numéros d'article. Pour ces raisons, la table de création suivante a du sens pour moi.

Scénario A:

CREATE TABLE product (
   sku            text PRIMARY KEY,
   name           text UNIQUE NOT NULL, -- alternate key
   price          numeric NOT NULL CHECK (price > 0),
   quantity       numeric NOT NULL CHECK (quantity > 0),
   item_number   text -- hmmm...
);

Cependant, j'ai deux problèmes avec cela.

  1. Parfois (peut-être 3% à 5% du temps), la norme Item_Number est en réalité égale au SKU. C'est-à-dire un de mes fournisseurs en particulier des affixes à leurs produits ce que je soupçonne, ce n'est pas une SKU unique globalement unique, façonnée après leur numéro d'article.

  2. Qu'il soit égal à la SKU ou non, la norme Item_Number (lorsqu'il existant) est presque suffisamment suffisante pour identifier de manière unique un produit dans le domaine de mon petit magasin.

Je suis inquiet de la normaliser cela à 3nf. Si l'article_number est parfois null, il ne peut évidemment pas être déclaré une clé alternative. Mais sémantiquement, c'est un identifiant unique, où il existe, dans tous les cas, je peux penser. Donc, ma table ci-dessus, où chaque attribut dépend de manière fonctionnelle de l'attribut non-prime item_number chaque fois que l'élément_number existe, normalisé? Je pense que non, mais je ne suis certainement pas un expert. J'ai pensé à faire ce qui suit:

Scénario b

CREATE TABLE product (
   sku            text PRIMARY KEY REFERENCES product_item_number (sku),
   name           text UNIQUE NOT NULL, -- alternate key
   price          numeric NOT NULL CHECK (price > 0),
   quantity       numeric NOT NULL CHECK (quantity > 0),
);

CREATE TABLE product_item_number (
   sku            text PRIMARY KEY,
   item_number    text
);

Étant donné qu'il n'est vraiment pas nécessaire que je préserve la dépendance fonctionnelle item_number -> prix, item_number -> Quantité, etc., scénario B Kinda Sorta semble raisonnable pour moi. Je n'aurai pas d'attribut non-prime déterminant d'autres attributs non principaux.

Ma dernière idée était de simplement utiliser le SKU comme numéro d'article dans tous les cas où la norme d'article est autrefois inexistante, mais je me demande si c'est une bonne pratique.

Scénario c

CREATE TABLE product (
   sku            text PRIMARY KEY,
   name           text UNIQUE NOT NULL, -- alternate key
   price          numeric NOT NULL CHECK (price > 0),
   quantity       numeric NOT NULL CHECK (quantity > 0),
   item_number    text UNIQUE NOT NULL -- alternate key???
);

Mon inquiétude avec le scénario C est qu'il peut y avoir des cas où un fournisseur recycle un numéro de catalogue avec un SKU différent (peut-être?) Ou des situations où deux fabricants font à la fois un "D57-Rouge" ou quelque chose comme ça. Dans ce cas, je pense que je devrais avoir à préfixer programmablement les noms d'offenser les noms de fabricants ou quelque chose comme ça.

Bien sûr, peut-être que je pensais tout cela.

Merci d'avoir lu. Quelques clarifications, conformément aux commentaires de MDCCL:

  • Un SKU sera toujours unique dans mon domaine (la petite quantité de SKU non globalement unique fournisseur fournisseur à condition que vous ayez peu de temps en collision).
  • L'article_number sera un attribut à face publique, utilisé à la fois par les clients et parfois pour identifier les produits. Par exemple, disons qu'un client passe mon site Web et m'appelle pour demander si j'ai xyz-blanc; L'élément_number aide à éliminer l'ambiguïté. Les numéros d'article sont uniques dans mon expérience (c'est-à-dire qu'il n'y a pas de contre-exemples dans mon inventaire), mais ce n'est pas une règle, en soi. Je pourrais avoir un nom de nommer de n ° numérique de collision d'espace un jour. Peut-être que cela se produisait, je préfixerais les trois premières lettres du nom du fabricant à la norme Item_Number.
  • item_numbers n'existe pas toujours. Je suppose que je pourrait Fournir une sorte de "norme de substitution de substitution" pour ceux sans un, mais un nombre d'éléments arbitraires serait contre-productif. Comme expliqué immédiatement ci-dessus, où une norme d'élément existe, il devrait exister pour m'aider à moi-même et mes clients de Disambiguez entre des produits. Ils pourraient croire qu'ils examinent le mauvais produit si le n ° nombre est quelque chose que je me suis concocté. Je ne suis pas sûr.
7
Harley

Si votre attribut item_number est unique, vous pouvez le laisser dans votre table d'origine, même si cela peut avoir des valeurs nulles. En fait, le postgreSQL manuel dit:

Aux fins d'une contrainte unique, les valeurs nulles ne sont pas considérées comme égales.

Cela pourrait donc être une solution correcte:

CREATE TABLE product (
   sku            text PRIMARY KEY,
   name           text UNIQUE NOT NULL,
   price          numeric NOT NULL CHECK (price > 0),
   quantity       numeric NOT NULL CHECK (quantity > 0),
   item_number    text UNIQUE
);

qui est plus efficace que la solution B et plus simple à programmer que la solution C.

Notez que cette solution est normalisée, de sorte que vous n'avez aucune redondance, ni vous avez des anomalies d'insertion/de suppression.

Ajout

Pour qu'une relation soit formellement sous forme de codd boyce, une forme normale (qui est plus stricte que la troisième forme normale), pour chaque dépendance, le déterminant doit être une touche (super). Mais notez d'abord que la théorie de la normalisation ne traite généralement pas les valeurs nulles. Voir par exemple le livre d'Elmasri, Navathe, "fondamental des systèmes de base de données". 6ème édition, 2010:

Il n'existe pas de théorie de conception relationnelle entièrement satisfaisante, cela inclut les valeurs nulles

Dans ce cas, nous avons au moins la dépendance:

sku → name, price, quantity, item_number

et en fait sku est une clé pour la relation.

Ensuite, supposant qu'il n'y ait pas de valeurs nulles, si vous voulez item_number Soyez unique, il existe une autre dépendance:

item_number → sku, name, price, quantity

et donc, item_number est une autre clé.

Dans cette relation, il n'y a pas d'autres dépendances fonctionnelles, une partie de celles dérivées de ces deux, et ces deux dépendances ne violent pas le BCNF (les deux déterminants sont des clés). Donc, la relation est dans la forme normale du codd Boyce.

D'autre part, si vous considérez que item_number Peut avoir des valeurs nulles, vous pouvez supposer que la deuxième dépendance ne tient pas, de sorte que la relation soit à nouveau dans BCNF.

3
Renzo