Base de données de conception / modélisation Question - Contraintes ou pas de contraintes?

StackOverflow https://stackoverflow.com/questions/1155058

  •  18-09-2019
  •  | 
  •  

Question

Compte tenu de la structure suivante:

City
Area
User

Chaque zone a 1 et seulement 1 ville.
Chaque utilisateur a au moins une, mais peut-être plusieurs zones.
Chaque utilisateur a 1 et seulement 1 Ville.

Quelle est la manière la plus élégante de modéliser cette?

À l'heure actuelle, je:

User,
UserArea,
Area,
City

Où UserArea est 1: relation M w / utilisateur, et la région est de 1: 1. Avec Ville

Le problème est le suivant:

Un utilisateur peut avoir 3 ou 4 zones sous le modèle actuel, mais deux des zones pourrait être dans la ville « 1 » et les 2 autres zones pourrait être dans la ville « 2 ». Ceci est une violation des règles commerciales.

Dois-je viens de mettre dans une contrainte pour éviter ce genre de chose, ou est une meilleure approche de normaliser davantage afin que ce type de paradoxe n'est pas possible? Si oui, comment un modèle de ce système de sorte que:

1 utilisateur = 1 Ville;
1 = Zone 1 Ville;
1 Utilisateur = Domaines M;

Merci pour vous des idées.

Était-ce utile?

La solution 7

Cette réponse m'a été fournie de SQLServerCentral, et il fait exactement ce que je cherchais. Il y a une redondance (comme rexum a souligné dans ce forum), mais il n'y a aucune possibilité de anomolies.

Je suis très intéressé par vos commentaires et suggestions.


CREATE TABLE [dbo].[Cities](
    [CityID] [int] IDENTITY(1,1) NOT NULL,
  [CityName] [varchar](50) NOT NULL,
 CONSTRAINT [PK_Cities] PRIMARY KEY CLUSTERED
(
   [CityID] ASC
)
)
CREATE TABLE [dbo].[Users](
   [UserID] [int] IDENTITY(1,1) NOT NULL,
  [UserName] [varchar](50) NOT NULL,
  [CityID] [int] NOT NULL,
 CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED
(
  [UserID] ASC
)
)

ALTER TABLE [dbo].[Users]  WITH CHECK ADD  CONSTRAINT [FK_Users_Cities] FOREIGN KEY([CityID])
REFERENCES [dbo].[Cities] ([CityID])
GO
ALTER TABLE [dbo].[Users] CHECK CONSTRAINT [FK_Users_Cities]
GO
CREATE UNIQUE NONCLUSTERED INDEX [IX_UsersCity] ON [dbo].[Users]
(
   [UserID] ASC,
   [CityID] ASC
)

CREATE TABLE [dbo].[Areas](
    [AreaID] [int] IDENTITY(1,1) NOT NULL,
  [AreaName] [varchar](50) NOT NULL,
  [CityID] [int] NOT NULL,
 CONSTRAINT [PK_Areas] PRIMARY KEY CLUSTERED
(
  [AreaID] ASC
))


GO
ALTER TABLE [dbo].[Areas]  WITH CHECK ADD  CONSTRAINT [FK_Areas_Cities] FOREIGN KEY([CityID])
REFERENCES [dbo].[Cities] ([CityID])
GO
ALTER TABLE [dbo].[Areas] CHECK CONSTRAINT [FK_Areas_Cities]
GO
CREATE UNIQUE NONCLUSTERED INDEX [IX_AreasCity] ON [dbo].[Areas]
(
 [AreaID] ASC,
   [CityID] ASC
)
GO
CREATE TABLE [dbo].[UserCityArea](
   [UserID] [int] NOT NULL,
    [CityID] [int] NOT NULL,
    [AreaID] [int] NOT NULL,
 CONSTRAINT [PK_UserCityArea] PRIMARY KEY CLUSTERED
(
   [UserID] ASC,
   [CityID] ASC,
   [AreaID] ASC
)
)

GO
ALTER TABLE [dbo].[UserCityArea]  WITH CHECK ADD FOREIGN KEY([UserID], [CityID])
REFERENCES [dbo].[Users] ([UserID], [CityID])
GO
ALTER TABLE [dbo].[UserCityArea]  WITH CHECK ADD FOREIGN KEY([AreaID], [CityID])
REFERENCES [dbo].[Areas] ([AreaID], [CityID])

Autres conseils

J'aurais une table pour chacun des utilisateurs, les zones et les villes, ont alors une quatrième table avec des colonnes utilisateur (FK), Villes (FK) et les zones (FK) où les utilisateurs et les villes (en combinaison) est contraint d'être unique . Ensuite, chaque fois qu'une combinaison utilisateur-zone est insérée, elle ne permettra pas une ville non unique.

La seule chose que je peux penser est désinvolture:

Donnez la table Surface composite clé alternative de CityID et Areaid. Faire primaire Areaid (donc il ne peut avoir qu'une seule ville).

Utilisez pour former une relation FK entre la zone et UserArea cette clé alternative (AK1).

Donner la table utilisateur un composite de clé alternative ID utilisateur et CityID. Faire primaire UserID.

Cette clé alternative (AK2), pour former une relation entre FK utilisateur et UserArea.

Ainsi, votre table UserArea ressemblera à ceci:

UserID CityID Areaid

La clé étrangère basée sur AK2 vous forcer à choisir une ville qui correspond à la ville natale de l'utilisateur et la clé étrangère basée sur AK1 vous forcer à choisir une région qui appartient à cette ville. Essentiellement, les clés étrangères AK1 et AK2 se chevauchent, ce qui oblige ce que vous voulez.

Je pense que votre approche « utilisateur, UserArea, secteur, ville » est correcte. Fiez-vous les contraintes et la logique métier pour prévenir les violations.

Pouvez-vous fournir plus de détails sur ce qui est une région? Permettez-moi mes hypothèses:
L'utilisateur vit dans une ville.
Chaque ville a des zones.
Une zone peut tomber dans une seule ville.
Un utilisateur peut vivre dans une seule ville
Compte tenu de ces conditions, vous semblez avoir les dépendances fonctionnelles suivantes dans vos spécifications de conception:
Zone -> Ville
Utilisateur -> Ville
Votre modèle d'affaires suggère que l'utilisateur peut avoir plusieurs adresses dans la même ville mais ne peut pas avoir une adresse dans deux villes différentes. Est-ce une contrainte de conception réaliste? Si je peux avoir plusieurs adresses, pourquoi pas dans différentes villes alors?
Si vous voulez stocker toutes les zones d'un utilisateur donné, vous avez besoin d'une troisième table (comme vous l'avez suggéré). Le tableau ressemblerait
UserArea (userID, Areaid). Vous devez implémenter la logique métier en utilisant un déclencheur ou une procédure stockée.

USER_AREAS ne nécessite que les colonnes suivantes:

  • USER_ID (pk, fk pour USERS.USER_ID)
  • AREA_ID (pk, fk pour AREA.AREA_ID)

Une zone est associée à une ville dans la table des domaines; vous savez quelles villes sont associées à l'utilisateur en roulant de la table ZONES:

AREA

  • AREA_ID (pk)
  • CITY-ID (fk pour CITY.CITY_ID)

Mettre CITY_ID dans la table USER_AREAS est redondant. En second lieu, plaçant CITY_ID dans la table USER_AREAS ne garantit pas que le AREA_ID dans ce dossier est effectivement associé à la CITY_ID dans la table AREA. Une contrainte de vérification applique seulement l'intégrité de domaine en limitant les valeurs qui sont acceptées par une colonne, et ne peut pas référencer des colonnes dans les autres tableaux doivent moins une fonction définie par l'utilisateur.

Vous ne pouvez pas appliquer la règle de gestion des zones d'un utilisateur ne jamais appartenant à une seule ville dans la base de données. Il devrait être fait au niveau de l'application (quel que soit sproc gère l'insertion / mise à jour de la table USER_AREAS).

Je ne sais pas ce que vous entendez par « zones ».

Je crois que la division urbaine est la suivante:

La planète a des pays. Un pays a des régions (états, provinces, etc.) Les régions ont des zones (villes, villes, villages, etc.) Zones (si elle est assez grande) peuvent avoir des districts.

Utilisateur => Pays + Région / + Ville (+ District)

Pourriez-vous s'il vous plaît donner des détails sur les domaines?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top