web-dev-qa-db-fra.com

'Villes' mérite-t-elle une table séparée?

J'ai la table des clients suivants:

customer_id - int 
company_name - nvarchar
street - nvarchar
city - nvarchar
comments - nvarchar

L'application ne sera utilisée que dans une partie d'un petit pays (quelque chose comme 30 villes). Un ami m'a dit que je devrais séparer "ville" dans une table différente des "villes" et n'utiliser que city_id dans la table des clients.

Personnellement, je n'ai pas vu beaucoup d'avantages (sauf pour économiser de l'espace sur la table des clients qui me semble insignifiante dans ce cas pour le coût de la création d'une autre table).

Il a également mentionné que parce que j'ai des colonnes en double - Ville: Foo, Ville: Bar, Ville: Foo. (Peu de clients dans la même ville) Ceci n'est pas considéré comme normalisé, est-ce vrai?

Qui a raison? Toute illumination sur le problème?

4
BornToCode

La conception ne répond pas troisième forme normale , mais pas seulement à cause de la ville. La rue Champs, la ville dépend de l'autre (si vous changez de la ville, la rue devrait probablement changer aussi bien et vice-versa). Vous pourriez également avoir la même rue, la combinaison de la ville représentée de différentes manières (Foo St, Foo; Foo Street, FOO; etc.).

Pour normaliser cela, vous créez une nouvelle adresse d'adresses de table qui a la rue, la ville, etc. Dans et relierait le client à celui via un identifiant d'adresse. Cela vous permettrait également de répertorier plusieurs adresses pour un client (via une table de liaison) si c'est ce dont vous avez besoin.

Cela vous laisse toujours décider s'il faut extraire la ville dans sa propre table. Pour rencontrer complètement 3NF, vous devez créer une table de villes, que vous ayez besoin ou que vous souhaitez dépendre de la réponse aux questions suivantes:

  1. Avez-vous (ou allez-vous) avoir des attributs supplémentaires de la ville (par exemple la population, le comté/l'état, le nom d'affichage, etc.)
  2. Exécutez-vous une requête pour générer une liste de villes distinctes à choisir (votre commentaire suggère oui)

Si le premier point est vrai, vous devriez certainement créer une table de villes, sinon vous pourriez vous retrouver avec une seule ville ayant des populations différentes, etc. Si la seconde est vraie, c'est une très bonne idée d'avoir une table séparée que la requête à la liste. Toutes vos villes vont échouer beaucoup mieux - vous ne devrez numériser que cette table plutôt que la table (presque certainement plus grande) de la table des clients, puis obtenir les villes distinctes de cela.

5
Chris Saxon

Lorsque vous entrez dessus - vraiment Entrez dans l'informatique - stocker des données d'adresse composés est un problème extrêmement compliqué en raison de tous les systèmes disparates et variés utilisés dans le monde entier.

Je pense que tout ce que vous développez doit être équilibré entre la flexibilité et ne stocker que ce qui votre Business doit stocker.


Le plus gros morceau du puzzle ici est de déplacer tous les champs liés à l'adresse de la table Customers - Les adresses sont des entités à eux-mêmes.

Le coût spatial peut ne pas être pertinent dans un très petit système (peut-être), mais il s'agit davantage d'une question de dette technique. Si vous devez commencer à ajouter plus de champs liés à l'adresse, vous devrez continuer à ajouter de plus en plus à la table Customers. Tôt ou tard, vous vous rendrez compte qu'il s'agit d'une conception inflexible - si vous devez utiliser plusieurs adresses pour un client donné (adresses de facturation et d'expédition étant l'exemple classique), vous êtes maintenant dans un monde de blessures sans normaliser, Comme vous ne pouvez pas réutiliser la structure existante pour stocker les données requises.

Au minimum absolu, créez une nouvelle table Addresses, puis référence address_id de Customers. Si vous souhaitez aller à l'itinéraire d'adresse à plusieurs reprises, je ne fais même que cette étape (par opposition à la conception actuelle) permettra d'économiser un maux de tête massif plus tard.

La ligne d'adresse pourrait aller soit directement dans la table Addresses directement pour la simplicité, soit dans une _ distincte Address_Lines table pour gérer plusieurs lignes. (Ce dernier est généralement préféré.)

Après cela, un minimum général pour pouvoir trancher et désigner vos données de manière significative consiste à construire une normalisation Countries, Regions (AKA provinces/territoires/etc.), et Cities tables, avec seulement celle-ci apparaissant comme un champ dans la table Addresses. Cela vous permet de poser des questions commerciales comme "Combien de produits avons-nous vendons-nous dans la ville x?" et "Combien de produits avons-nous vendons-nous dans la région Y?". (Remarque: En fonction de l'endroit où vous utilisez, quelles données vous avez et comment les données seront tranchées, vous pouvez avoir besoin d'une 4ème table dans la table entre Regions et Cities.)

Si vous avez besoin d'obtenir plus de granular ("Combien de produits avons-nous vendons-nous à des clients sur la rue X?"), Vous devrez alors commencer à composeriser les lignes d'adresse elles-mêmes, qui est la partie vraiment difficile. Habituellement, cependant, une entreprise ne posera pas ce genre de question. Étant donné que je ne vois même pas de champ de code postal, je suppose que ce n'est pas quelque chose que vous aimez.

6
Jon Seigel

La modélisation de l'adresse n'est pas universelle. Une implémentation universelle serait trop complexe pour la plupart des applications. Les différents modèles varient selon le type de modèle (OLTP VS OLAP), les règles de pays, le type de client (organisation vs individuel), quelle que soit la critique des données d'adresse, etc.

Comme dit, vous devriez séparer la ville. Séparer la ville fera le problème d'avoir différents noms de villes dans la table des clients disparaître. Les raisons sont:

1 - La séparation des noms de ville dans une table séparée vous permet d'exécuter des questions telles que: Donnez-moi une distribution client par ville et d'afficher des villes où aucun client n'est présent.

2 - Vous permet de toujours vous référer à la liste correcte des villes.

3 - Vous permet de maintenir des informations sur la ville sans toucher votre code de programme.

4 - Permet des noms de ville en double (dans différents états) si vous utilisez le diagramme ci-dessous.

Si vous êtes sûr que votre demande est pour 1 pays, vous n'ajoutez pas le pays.

De plus, j'ai remarqué que vous ne séparez pas les informations d'adresse de la rue dans 2 colonnes qui sont communes en Amérique du Nord et que vous n'avez pas de code postal. Passez en revue les exigences de l'adresse postale du pays des autorités postales pour vous assurer que votre conception est conforme à eux.

Voici une représentation commune de l'adresse dans un OLTP Application. Ici, le PK de la ville est 2 colonnes, nommément, Vility et Stateid. Une variation de cette version serait d'utiliser un seul identifiant pour chaque table. (en tant que numéro de séquence) et finissez par un FK composé de 1 colonne uniquement à la table du client.

Tout se résume aux règles et aux exigences de l'entreprise.

enter image description here

Ce qui suit est une représentation de base.

2
NoChance

Pour normaliser la conception, vous devez séparer la ville. En plus d'économiser de l'espace, son bon design. Aussi atténue les entrées de nom de la ville en double, comme Foo, Foo, Fooo, etc. et vous pouvez avoir des détails spécifiques à la ville de cette table comme code postal.

1
Shiva

Il a également mentionné que parce que j'ai des colonnes en double - Ville: Foo, Ville: Bar, Ville: Foo. (Peu de clients dans la même ville) Ceci n'est pas considéré comme normalisé, est-ce vrai?

Le article Wikipedia sur 3NF dit: une table est en 3NF si et seulement si, pour chacune de ses dépendances fonctionnelles x → A, au moins une des conditions suivantes contient:

  • X contient un (c'est-à-dire x → a est une dépendance fonctionnelle triviale)
  • Ou x est un superbe
  • A-X, la différence définie entre A et X est un attribut prime (c'est-à-dire A-X figurant dans une clé candidate)

City ne peut pas être dit fonctionnellement dépendant de lui-même. Donc, la répétition de valeurs identiques dans différentes lignes ne violait pas 3NF.

Pour un exemple qui violerait 3NF, ajoutez CityPopulation à la table. Maintenant, il existe une dépendance fonctionnelle pour X = (city) et A = (CityPopulation). Cette dépendance ne satisfait aucune des trois conditions et cette conception de table violerait la forme normale.

Cela dit, je pense que la normalisation est un exercice académique inutile. S'efforcer de la conformité 3NF dans une base de données est une catastrophe garantie.

1
Andomar