Frage zum Datenbankdesign/-modellierung – Einschränkungen oder keine Einschränkungen?

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

  •  18-09-2019
  •  | 
  •  

Frage

Angesichts der folgenden Struktur:

City
Area
User

Jedes Gebiet hat 1 und nur 1 Stadt.
Jeder Benutzer verfügt über mindestens einen, möglicherweise jedoch mehrere Bereiche.
Jeder Benutzer hat 1 und nur 1 Stadt.

Wie lässt sich das am elegantesten modellieren?

Derzeit habe ich:

User,
UserArea,
Area,
City

Dabei ist UserArea eine 1:M-Beziehung mit dem Benutzer und Area eine 1:1-Beziehung mit der Stadt.

Das Problem ist folgendes:

Ein Benutzer kann im aktuellen Modell 3 oder 4 Bereiche haben, aber 2 der Bereiche könnten sich in der Stadt „1“ befinden und die anderen 2 Bereiche könnten sich in der Stadt „2“ befinden.Dies ist ein Verstoß gegen Geschäftsregeln.

Sollte ich einfach eine Einschränkung einführen, um so etwas zu verhindern, oder ist es besser, weiter zu normalisieren, sodass diese Art von Paradoxon nicht möglich ist?Wenn ja, wie modelliert man dieses System so, dass:

1 Benutzer = 1 Stadt;
1 Gebiet = 1 Stadt;
1 Benutzer = M Bereiche;

Vielen Dank für Ihre Einblicke.

War es hilfreich?

Lösung 7

Diese Antwort wurde mir von SQLServercentral gegeben und genau das tut, wonach ich gesucht habe. Es gibt eine Redundanz (wie Rexum in diesem Forum hervorhob), aber es gibt keine Möglichkeit von Anomolien.

Ich interessiere mich sehr für Ihre Kommentare und Vorschläge.


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

Andere Tipps

Ich hätte jeweils eine Tabelle für Benutzer, Bereiche und Städte und dann eine vierte Tabelle mit Spaltenbenutzer (FK), Städten (FK) und Bereichen (FK), in denen Benutzer und Städte (in Kombination) eindeutig sind. Wenn dann eine Kombination aus Benutzerbereich eingefügt wird, wird eine nicht eindeutige Stadt nicht zulässt.

Ich kann mir nur nicht vorstellen:

Geben Sie der Fläche einen zusammengesetzten alternativen Schlüssel von Cityid und AreaID. Machen Sie AreaId Primary (damit es nur eine Stadt haben kann).

Verwenden Sie diesen alternativen Schlüssel (AK1), um eine FK -Beziehung zwischen Bereich und Benutzerbereich zu bilden.

Geben Sie der Benutzertabelle einen zusammengesetzten alternativen Taste von UserID und CityID an. UserID primär machen.

Verwenden Sie diesen alternativen Schlüssel (AK2), um eine FK -Beziehung zwischen Benutzer und Benutzerbereich zu bilden.

Ihre Benutzerbereichstabelle sieht also so aus:

Userid Cityid AreaId

Der in AK2 ansässige ausländische Schlüssel wird Sie dazu zwingen, eine Stadt auszuwählen, die der Heimatstadt des Benutzers entspricht, und der aus dem AK1 ansässige ausländische Schlüssel wird Sie dazu zwingen, ein Gebiet auszuwählen, das dieser Stadt gehört. Im Wesentlichen überschneiden sich AK1 und AK2 Foreign Keys und erzwingen, was Sie wollen.

Ich denke, dass Ihr Ansatz "Benutzer, Benutzerbereich, Bereich, Stadt" korrekt ist. Verlassen Sie sich auf die Einschränkungen und Geschäftslogik, um Verstöße zu verhindern.

Können Sie nähere Angaben dazu machen, was ein Gebiet ist?Lassen Sie mich meine Annahmen darlegen:
Benutzer lebt in einer Stadt.
Jede Stadt hat Gebiete.
Ein Gebiet kann nur zu einer Stadt gehören.
Ein Benutzer kann nur in einer Stadt leben
Unter diesen Bedingungen scheinen in Ihrer Designspezifikation die folgenden funktionalen Abhängigkeiten zu bestehen:
Gebiet -> Stadt
Benutzer -> Stadt
Ihr Geschäftsmodell sieht vor, dass der Benutzer mehrere Adressen innerhalb derselben Stadt haben kann, jedoch keine Adresse in zwei verschiedenen Städten.Ist dies eine realistische Designbeschränkung?Wenn ich mehrere Adressen haben kann, warum dann nicht in verschiedenen Städten?
Wenn Sie alle Bereiche eines bestimmten Benutzers speichern möchten, benötigen Sie eine dritte Tabelle (wie Sie vorgeschlagen haben).Der Tisch würde so aussehen
Benutzerbereich(Benutzer-ID,Bereichs-ID).Sie müssen die Geschäftslogik mithilfe eines Triggers oder einer gespeicherten Prozedur implementieren.

USER_AREAS erfordert nur die folgenden Spalten:

  • USER_ID (PK, FK für USERS.USER_ID)
  • AREA_ID (PK, FK für AREA.AREA_ID)

Ein Gebiet ist mit einer Stadt im Bereich der Gebiete verbunden. Sie wissen, welche Städte mit dem Benutzer zugeordnet sind, indem Sie aus dem Bereich der Bereiche aufrollen:

AREA

  • AREA_ID (PK)
  • CITY-ID (FK für CITY.CITY_ID)

Putten CITY_ID in dem USER_AREAS Tabelle ist überflüssig. Zweitens platzieren CITY_ID in dem USER_AREAS Tabelle garantiert nicht, dass die AREA_ID in diesem Datensatz ist tatsächlich mit dem verbunden CITY_ID im Bereich Tisch. Eine Überprüfungsbeschränkung erzwingt nur die Domänenintegrität, indem die Werte, die von einer Spalte akzeptiert werden, begrenzt werden und die Spalten in anderen Tabellen nicht referenzieren können, müssen weniger eine benutzerdefinierte Funktion haben.

Sie können die Geschäftsregel der Bereiche eines Benutzers nicht durchsetzen, die nur zu einer einzigen Stadt in der Datenbank gehören. Es müsste auf Anwendungsebene durchgeführt werden (was auch immer SPOC es verwaltet, das Einfügen/Aktualisieren der USER_AREAS Tisch).

Ich bin mir nicht sicher, was Sie mit "Bereichen" meinen.

Ich glaube, die Stadtabteilung ist wie folgt:

Der Planet hat Länder. Ein Land hat Regionen (Staaten, Provinzen usw.) Regionen verfügen über Gebiete (Städte, Städte, Dörfer usw.) (falls groß genug) Distrikte.

Benutzer => Land + Region/Gebiet + Stadt ( + Distrikt)

Könnten Sie bitte Bereiche näher erläutern?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top