سؤال

لدي سؤال سريع بشأن قاعدة بيانات أقوم بتصميمها والتأكد من تطبيعها ...

لدي جدول عملاء ، مع مفتاح أساسي لـ CustomerId. يحتوي على عمود رمز الحالة الذي يحتوي على رمز يعكس حالة حساب العملاء على سبيل المثال. 1 = مفتوح ، 2 = مغلق ، 3 = معلق الخ ...

الآن أرغب في الحصول على حقل آخر في جدول العميل يعلق ما إذا كان يتم السماح للحساب بتعليقه أم لا ... سيتم تعليق بعض العملاء تلقائيًا إذا كسروا هناك شروط تداول ... أخرى ليست ... حقول الجدول ستكون كذلك:

العملاء (CustomerId (PK): statuscode: issuspensioned)

الآن يعتمد كلا الحقلين على المفتاح الأساسي حيث لا يمكنك تحديد الحالة أو ما إذا كان التعليق مسموح به على عميل معين ما لم تكن تعرف العميل المحدد ، باستثناء بالطبع عندما يتم تعيين الحقل المسموح به على نعم ، يجب ألا يكون لدى العميل أبدًا رمز الحالة 3 (مع وقف التنفيذ).

يبدو من تصميم الجدول أعلاه أنه من الممكن أن يحدث هذا ما لم تتم إضافة مساهمة فحص إلى طاولتي. لا أستطيع أن أرى كيف يمكن إضافة جدول آخر إلى التصميم العلائقي لفرض ذلك على الرغم من أنه فقط في الحالة التي يتم فيها تعيين issuspensioned على نعم ، ويتم ضبط رمز الحالة على 3 عندما يكون للثاني الاعتماد على بعضهما البعض.

لذا ، بعد شرحتي الطويلة ، سؤالي هو: هل هذه مشكلة تطبيع ولا أرى تصميمًا علائقيًا من شأنه أن ينفذ هذا ... أم أنه في الواقع مجرد قاعدة عمل يجب أن يتم تنفيذها مع مسالفة فحص و الجدول في الواقع لا يزال تطبيع.

هتافات،

ستيف

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

المحلول

نعم هذا ممكن. يمكنك القيام بذلك مع قيود الشيك وبيان الحالة:

Create Table Customer   (
        CustomerId <datatype> not null Primary Key
        , StatusCode int not null
        , IsSuspensionAllowed int not null Default( 1 )
        , Constraint CK_Customer_IsSuspensionAllowed 
                    Check ( IsSuspensionAllowed In(0,1) )
        , Constraint CK_Customer_StatusCodeRange 
                    Check ( StatusCode Between 0 And ?? )
        , Constraint CK_Customer_StausCodeValid 
                    Check ( Case
                When StatusCode = 3 And IsSuspensionAllowed = 1 Then 0
                                                                Else 1
                                                                End = 1 )
        , ....
        )

لم تذكر نوع بيانات PK ، لذا قمت ببساطة بإدراج عنصر نائب. إذا كنت تستخدم SQL Server ، يمكنك استخدام عمود بت بدلاً من int والتحقق من القيد الذي ذكرته أعلاه (bit ليس جزءًا من مواصفات ANSI).

هذا مثال جيد على المكان الذي لا تعمل فيه مفاتيح البديل لأشياء مثل رموز الحالة بشكل جيد. سيكون من الأفضل أن تمثل قيم السلسلة رموز الحالة في هذه الحالة التي ستقرأ فيها عبارة الحالة When StatusCode = 'Suspended' And IsSuspendedAllowed = 0....

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

راجع للشغل ، ألا يكون من المنطقي أن نقول أن حالة "تعليق" غير مسموح بها عند إدراج issuspensioned = 0؟ باستخدام بياناتك ، ألا ينبغي أن تكون الحالة غير مسموح بها StatusCode = 3 and IsSuspensionAllowed = 0?

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