データベースの設計/モデリングの質問 - 制約または制約なし?
-
18-09-2019 - |
質問
次の構造を考えると、
City
Area
User
すべてのエリアには、1つと1つの都市のみがあります。
すべてのユーザーには、少なくとも1つですが、おそらく複数の領域があります。
すべてのユーザーには1つの都市と1つの都市のみがあります。
これをモデル化する最もエレガントな方法は何ですか?
現在、私は持っています:
User,
UserArea,
Area,
City
UserAreaはユーザーの1:M関係で、エリアは都市で1:1です。
問題はこれです:
ユーザーは現在のモデルの下に3つまたは4つのエリアを持つことができますが、2つのエリアは都市「1」にあり、他の2つのエリアは都市「2」にある可能性があります。これはビジネスルールの違反です。
この種のことを防ぐために制約を抑えるべきですか、それともこのタイプのパラドックスが不可能になるようにさらに正常化するためのより良いアプローチですか?もしそうなら、このシステムをどのようにモデル化するのか:
1ユーザー= 1 City;
1エリア= 1市;
1ユーザー= Mエリア。
洞察をありがとう。
解決 7
この答えは、SQLServerCentralから私に提供され、それは私が探していたものを正確に行います。冗長性があります(このフォーラムでRexumが指摘したように)が、アノモリーの可能性はありません。
私はあなたのコメントと提案にとても興味があります。
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])
他のヒント
ユーザー、エリア、都市用のテーブルがあり、列ユーザー(FK)、都市(FK)、エリア(FK)を備えた4番目のテーブルがあり、ユーザーと都市(組み合わせて)が一意に制約されます。その後、ユーザーエリアの組み合わせが挿入されるたびに、非ユニークな都市は許可されません。
私がオフハンドで考えることができる唯一のことは、次のとおりです。
エリアテーブルに、CityIDとAreaIDの複合代替キーを与えます。エリアドプライマリを作成します(1つの都市しか持たないように)。
この代替キー(AK1)を使用して、エリアとユーザーレアの間にFK関係を形成します。
ユーザーテーブルに、useridとcityidの複合代替キーを与えます。ユーザーIDプライマリを作成します。
この代替キー(AK2)を使用して、ユーザーとUserAreaの間にFK関係を形成します。
したがって、ユーザーアレアテーブルは次のようになります。
userid cityid areaid
AK2ベースの外部キーは、ユーザーの故郷の都市に合った都市を選ぶことを強制します。AK1ベースの外部キーは、その都市に属するエリアを選ぶように強制されます。本質的に、AK1とAK2の外国キーは重複し、あなたが望むものを強制します。
「ユーザー、ユーザーアレア、エリア、都市」アプローチが正しいと思います。違反を防ぐために、制約とビジネスロジックに頼ってください。
エリアとは何かについて詳細を提供できますか?私の仮定を述べさせてください:
ユーザーは都市に住んでいます。
すべての都市にはエリアがあります。
エリアは1つの都市だけに分類されます。
ユーザーは1つの都市にのみ住むことができます
これらの条件を考えると、設計仕様に次の機能依存関係があるようです。
エリア - >都市
ユーザー - > City
あなたのビジネスモデルは、ユーザーが同じ都市内に複数の住所を持つことができるが、2つの異なる都市に住所を持つことができないことを示唆しています。これは現実的なデザインの制約ですか?複数のアドレスを持つことができる場合、別の都市ではなぜですか?
特定のユーザーのすべての領域を保存する場合は、3番目のテーブルが必要です(提案したように)。テーブルはどのように見えますか
userarea(userid、areaid)。トリガーまたはストアドプロシージャを使用してビジネスロジックを実装する必要があります。
USER_AREAS
次の列のみが必要です。
USER_ID
(pk、fk forUSERS.USER_ID
)AREA_ID
(pk、fk forAREA.AREA_ID
)
エリアは、エリアテーブルの1つの都市に関連付けられています。エリアテーブルからロールアップすることにより、どの都市がユーザーに関連付けられているかを知っています。
AREA
AREA_ID
(PK)CITY-ID
(fk forCITY.CITY_ID
)
パッティング CITY_ID
の中に USER_AREAS
テーブルは冗長です。第二に、配置 CITY_ID
の中に USER_AREAS
テーブルはそれを保証しません AREA_ID
そのレコードでは、実際にはに関連付けられています CITY_ID
エリアテーブルで。チェック制約は、列で受け入れられている値を制限することにより、ドメインの整合性を強制し、他のテーブルの列を参照できない必要がありません。
データベース内の単一の都市にのみ属するユーザーの領域のビジネスルールを実施することはできません。アプリケーションレベルで行う必要があります(SPROCが挿入/更新を管理するものは何でも USER_AREAS
テーブル)。
「エリア」とはどういう意味かわかりません。
都市部は次のとおりです。
惑星には国があります。国には地域(州、州など)の地域には、地域(都市、町、村など)がある地域(十分に大きい場合)がある地域を持っています。
ユーザー=>国 +地域/エリア +都市( +地区)
エリアについて詳しく説明していただけませんか。