تصميم قاعدة البيانات / النمذجة السؤال - القيود أو عدم وجود قيود؟

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

  •  18-09-2019
  •  | 
  •  

سؤال

بالنظر إلى الهيكل التالي:

City
Area
User

كل منطقة لديها 1 ومدينة واحدة فقط.
كل مستخدم لديه واحد على الأقل ولكن مناطق متعددة.
كل مستخدم لديه 1 ومدينة واحدة فقط.

ما هي الطريقة الأكثر أناقة لنموذج هذا؟

حاليا، لدي:

User,
UserArea,
Area,
City

حيث UserArea هي العلاقة 1: m W / المستخدم، والمنطقة هي 1: 1 مع المدينة.

المشكلة هي:

يمكن للمستخدم الحصول على 3 أو 4 مناطق بموجب النموذج الحالي، ولكن 2 من المناطق يمكن أن تكون في المدينة "1" والمناطق الأخرى 2 يمكن أن تكون في المدينة "2". هذا انتهاك لقواعد الأعمال.

هل يجب علي وضع عائق لمنع هذا النوع من الأشياء، أو هو أفضل نهج للتطبيع أكثر بحيث لا يكون هذا النوع من المفارقة غير ممكن؟ إذا كان الأمر كذلك، كيف يقوم هذا النظام بنموذج واحد بحيث:

1 مستخدم = 1 مدينة؛
1 منطقة = 1 مدينة؛
1 مستخدم = م.

شكرا لك رؤى.

هل كانت مفيدة؟

المحلول 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) حيث يتم تقييد المستخدمين والمدن (بالاشتراك). ثم عند إدراج مجموعة من المساحات للمستخدم، لن تسمح بمدينة غير فريدة من نوعها.

الشيء الوحيد الذي يمكنني التفكير فيه هو:

امنح الجدول في المنطقة مفتاحا بديلا مركبا من CityID و AraleID. جعل الابتدائية الرومانية (لذلك يمكن أن يكون لديها مدينة واحدة فقط).

استخدم هذا المفتاح البديل (AK1) لتشكيل علاقة FK بين المنطقة و UserArea.

امنح جدول المستخدم مفتاحا بديلا مركبا من Userid و CityID. جعل معرف المستخدم الأساسي.

استخدم هذا المفتاح البديل (AK2) لتشكيل علاقة FK بين المستخدم و UserArea.

لذلك سيظهر جدول UserArea الخاص بك هذا:

userid areaid areaid.

سيجبرك المفتاح الأجنبي القائم على AK2 على اختيار مدينة تتطابق مع مدينة المستخدم الرئيسية، وسوف يجبرك المفتاح الأجنبي الذي يتخذ من AK1 على اختيار منطقة تنتمي إلى تلك المدينة. في جوهرها، سوف تتداخل مفاتيح AK1 و AK2، مما أجبر ما تريد.

أعتقد أن "مستخدمك، UserArea، المنطقة، المدينة، المدينة" هو الصحيح. الاعتماد على القيود ومنطق الأعمال لمنع الانتهاكات.

هل يمكنك تقديم المزيد من التفاصيل حول ما هي المنطقة؟ اسمحوا لي أن أذكر افتراضاتي:
يعيش المستخدم في مدينة.
كل مدينة لديها مناطق.
يمكن أن تقع المنطقة في مدينة واحدة فقط.
يمكن للمستخدم أن يعيش في مدينة واحدة فقط
بالنظر إلى هذه الشروط، يبدو أن لديك التبعيات الوظيفية التالية في مواصفات التصميم الخاصة بك:
المنطقة -> المدينة
المستخدم -> المدينة
يشير نموذج عملك إلى أن المستخدم يمكن أن يكون له عناوين متعددة داخل نفس المدينة ولكن لا يمكن أن يكون له عنوان في مدينتين مختلفتين. هل هذا قيد التصميم الواقعي؟ إذا كان بإمكاني الحصول على عدة عناوين، فلماذا لا في مدن مختلفة إذن؟
إذا كنت ترغب في تخزين جميع مجالات المستخدم المعطى، فأنت بحاجة إلى جدول ثالث (مثلك اقترح). سوف يبدو الجدول
UserArea (معرف المستخدم، Olloadaid). تحتاج إلى تنفيذ منطق الأعمال باستخدام الزناد أو إجراء مخزن.

USER_AREAS يتطلب فقط الأعمدة التالية:

  • USER_ID (PK، FK ل USERS.USER_ID)
  • AREA_ID (PK، FK ل AREA.AREA_ID)

ترتبط المنطقة بمدينة واحدة في طاولة المجالات؛ أنت تعرف أي المدن المرتبطة بالمستخدم عن طريق المتداول من جدول المجالات:

AREA

  • AREA_ID (PK)
  • CITY-ID (fk ل CITY.CITY_ID)

وضع CITY_ID في ال USER_AREAS الجدول زائد. ثانيا، وضع CITY_ID في ال USER_AREAS الجدول لا يضمن أن AREA_ID في هذا السجل مرتبط بالفعل بال CITY_ID في طاولة المنطقة. يفرض قيد الشيك يفرض فقط سلامة المجال فقط عن طريق الحد من القيم التي يتم قبولها بواسطة عمود، ولا يمكن أن تكون الأعمدة المرجعية في جداول أخرى أقل وظيفة محددة من المستخدمين.

لا يمكنك إنفاذ قاعدة الأعمال لمناطق المستخدم التي تنتمي إلا إلى مدينة واحدة في قاعدة البيانات. يجب أن يتم ذلك على مستوى التطبيق (مهما تدير Sproc إدراج / تحديث USER_AREAS جدول).

لست متأكدا مما تقصد به "المناطق".

أعتقد أن الانقسام الحضري على النحو التالي:

الكوكب لديه بلدان. لدى بلد مناطق (الدول والمقاطعات وما إلى ذلك) مناطق (المدن والبلدات والقرى وما إلى ذلك) مناطق (إذا كانت كبيرة بما فيه الكفاية) يمكن أن يكون لها مناطق.

User => بلد + + منطقة / منطقة + مدينة (+ منطقة)

هل يمكن أن يرجى توضيح المناطق؟

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top