Domanda

Data la seguente struttura:

City
Area
User

Ogni Area ha 1 e solo 1 City.
Ogni utente ha almeno uno, ma forse più aree.
Ogni utente ha 1 e solo 1 Città.

Qual è il modo più elegante per modellare questo?

Al momento, ho:

User,
UserArea,
Area,
City

Dove UserArea è una relazione 1: M w / utente, e la zona è 1: 1. Con Città

Il problema è questo:

Un utente può avere 3 o 4 aree sotto il modello attuale, ma 2 dei quartieri potrebbe essere in città "1" e le altre 2 aree potrebbero essere in città "2". Questa è una violazione delle regole di business.

Devo appena messo in un vincolo per impedire questo genere di cose, o è un approccio migliore per normalizzare ulteriormente, in modo che questo tipo di paradosso, non è possibile? Se sì, come si fa a modello questo sistema in modo che:

1 utente = 1 Città;
1 Area = 1 Città;
1 utente = M naturali;

Grazie per aver intuizioni.

È stato utile?

Soluzione 7

Questa risposta è stata fornita a me da SQLServerCentral, e fa esattamente quello che stavo cercando. C'è una ridondanza (come rexum ha sottolineato in questo forum), ma non v'è alcuna possibilità di anomalie.

Sono molto interessato a vostri commenti e suggerimenti.


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])

Altri suggerimenti

avrei un tavolo ciascuno per gli utenti, Aree e delle città, poi una quarta tabella con colonne utente (FK), Città (FK) e Areas (FK), dove utenti e delle città (in combinazione) è costretto ad essere unico . Poi ogni volta che viene inserita una combinazione di User-Area, non permetterà una Città non univoco.

L'unica cosa che mi viene in mente è sbrigativo:

Dare il tavolo area una chiave alternativa composita di cityID e areaid. Fare areaid primaria (in modo che possa avere una sola città).

Con questo tasto si alternano (AK1) per formare un rapporto FK Area e UserArea mezzo.

Dare tabella utenti una chiave alternativa composita di UserID e cityID. Fare primaria UserID.

Con questo tasto si alternano (AK2) per formare un rapporto FK tra utente e UserArea.

Così il vostro tavolo UserArea sarà simile a questa:

UserID cityID Areaid

La chiave esterna AK2-based vi costringerà a scegliere una città che corrisponde città home dell'utente, e la chiave esterna AK1-based vi costringerà a scegliere una zona che appartiene a quella città. In sostanza, AK1 e AK2 chiavi esterne si sovrapporranno, costringendo ciò che si desidera.

Penso che il vostro "User, UserArea, Area, City" approccio è corretto. Contare sulla vincoli e di business logica per prevenire le violazioni.

Si può fornire maggiori dettagli su ciò che è una zona? Vorrei dire la mia ipotesi:
Utente vive in una città.
Ogni città ha aree.
Una zona può cadere in una città unica.
Un utente può vivere in una città solo
Date queste condizioni, sembra che tu abbia le seguenti dipendenze funzionali nelle specifiche di progettazione:
Area -> Città
Utente -> Città
Il vostro modello di business suggerisce che l'utente può avere più indirizzi all'interno della stessa città, ma non possono utilizzare un indirizzo in due città diverse. Si tratta di un vincolo di design realistico? Se posso avere più indirizzi, perché non in diverse città allora?
Se si desidera memorizzare tutte le aree di un determinato utente è necessario un terzo tavolo (come avete suggerito). La tabella sarà simile
UserArea (userID, areaid). È necessario implementare la logica di business utilizzando un trigger o una stored procedure.

USER_AREAS richiede solo le seguenti colonne:

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

Una zona è associata a una città nella tabella AREE; si sa che le città sono associati con l'utente facendo rotolare dal tavolo AREE:

AREA

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

Mettere CITY_ID nella tabella USER_AREAS è ridondante. In secondo luogo, ponendo CITY_ID nella tabella USER_AREAS non garantisce che il AREA_ID in tale record è in realtà associato con la CITY_ID nella tabella AREA. Un vincolo CHECK impone soltanto integrità dominio limitando i valori che sono accettati da una colonna, e non possono fare riferimento alle colonne in altre tabelle devono meno una funzione definita dall'utente.

Non è possibile applicare la regola aziendale di aree di un utente sempre e solo appartenenti ad una singola città nel database. Avrebbe dovuto essere fatto a livello di applicazione (qualunque sproc gestisce l'inserimento / aggiornamento della tabella USER_AREAS).

Non sono sicuro di cosa si intende per "aree".

Credo che la divisione urbana è la seguente:

Il pianeta ha i paesi. Un paese ha regioni (stati, province ecc) Le Regioni hanno aree (città, paesi, villaggi etc.) Aree (se abbastanza grande) possono avere distretti.

User => Paese + Regione / Area + City (+ District)

La prego di approfondire aree?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top