أفضل الممارسات:تخزين حالة سير العمل لعنصر في قاعدة بيانات؟

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

سؤال

لدي سؤال حول أفضل الممارسات فيما يتعلق بكيفية التعامل مع تخزين حالات سير العمل المعقدة لمعالجة المهام في قاعدة البيانات.لقد كنت أبحث على الإنترنت دون جدوى، لذلك قررت أن أسأل المجتمع عما يعتقدون أنه الأفضل.

يأتي هذا السؤال من نفس مثال "BoxItem" الذي قدمته في سؤال سابق.يتم تتبع "BoxItem" هذا في نظامي حيث يتم تنفيذ مهام مختلفة عليه.قد تتم المهمة على مدار عدة أيام وبتفاعل بشري، لذلك يجب أن تستمر حالة BoxItem.من قام بالمهمة (إن أمكن)، ومتى تم إنجاز المهمة، يجب أيضًا تعقبه.

في البداية، تعاملت مع هذا الأمر عن طريق إضافة ثلاثة حقول إلى جدول "BoxItems" لكل مهمة تفاعلية بشرية يتعين القيام بها:

يكوناسم المهمةمكتمل

تاريخاسم المهمةمكتمل

مستخدماسم المهمةمكتمل

نجح هذا عندما كان سير العمل بسيطًا ...ولكن الآن بعد أن تطورت إلى عملية معقدة (> 10 تفاعلات بشرية محتملة في التدفق ...حوالي نصفها اختياري، وقد يتم أو لا يتم إجراؤها لـ BoxItem، مما أدى إلى البدء في إضافة "Doاسم المهمة"الحقول أيضًا لتلك المهام الاختيارية)، لقد وجدت أن ما كان ينبغي أن يكون جدولًا بسيطًا يحتوي الآن على 40 حقلًا أو نحو ذلك مخصصًا بالكامل للاحتفاظ بمعلومات الحالة هذه.

أجد نفسي أسأل إذا لم تكن هناك طريقة أفضل للقيام بذلك ...لكنني في حيرة.

كانت فكرتي الأولى هي إنشاء جدول "BoxItemTasks" عام يحدد المهام التي يمكن إجراؤها في مربع معين، ولكن ما زلت بحاجة إلى حفظ التاريخ ومعلومات المستخدم بشكل فردي، لذلك لم يساعد ذلك حقًا.

فكرتي الثانية هي أنه ربما لا يهم، ولا ينبغي لي أن أقلق إذا كان هذا الجدول يحتوي على 40 حقلاً أو أكثر مخصصة للاحتفاظ بالحالة...وربما أكون مجرد بجنون العظمة.ولكن يبدو أن هناك الكثير من المعلومات التي يجب الاحتفاظ بها.

على أي حال، أنا في حيرة بشأن ما قد يكون عليه الخيار الثالث، أو إذا كان أحد الخيارين أعلاه معقولًا بالفعل.أستطيع أن أرى أن سير العمل هذا من المحتمل أن يصبح أكثر تعقيدًا في المستقبل، ولكل مهمة جديدة سأحتاج إلى إضافة 3-4 حقول فقط لدعم تتبعها...يبدو الأمر وكأنه يخرج عن نطاق السيطرة.

ماذا كنت تفعل في هذه الحالة؟

يجب أن أشير إلى أن هذه صيانة لنظام موجود، وهو نظام تم إنشاؤه بدون ORM، لذا لا يمكنني أن أترك الأمر لـ ORM للعناية به.

يحرر:

كيف، هل تتحدث عن القيام بشيء مثل هذا:

BoxItems

(PK) معرف BoxItemID

(أشياء أخرى لا علاقة لها بالموضوع)

BoxItemActions

(PK) معرف BoxItemID

(PK) BoxItemTaskID

قد اكتمل

تاريخ الإكتمال

اكتمل المستخدم

BoxItemTasks

(PK) نوع المهمة

الوصف (إذا لزم الأمر)

همم...من شأنه أن يعمل...قد يمثل ذلك حاجة إلى تغيير الطريقة التي أتعامل بها حاليًا مع استعلامات SQL لمعرفة العناصر الموجودة في أي حالة، ولكن على المدى الطويل يبدو أن شيئًا كهذا سيعمل بشكل أفضل (دون الحاجة إلى إجراء تغيير أساسي في التصميم مثل فكرة التسلسل يمثل...على الرغم من أنه إذا كان لدي الوقت، أود أن أفعل ذلك بهذه الطريقة على ما أعتقد.).

فهل هذا ما كنت تذكره يا كين أم أنني خارج نطاقه؟

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

تعديل نهائي:لذا باختصار، إذا كان أي شخص آخر يبحث عن هذا في المستقبل ويطرح نفس السؤال...يبدو أن أسلوب التسلسل سيكون مفيدًا إذا كان نظامك يحتوي على المعلومات المحملة مسبقًا في بعض الواجهات حيث يمكن الاستعلام عنها (على سبيل المثال.لا تتصل مباشرة بقاعدة البيانات نفسها، كما يفعل النظام المخصص الذي أعمل عليه)، ولكن إذا لم يكن لديك ذلك، يبدو أن فكرة الجداول الإضافية يجب أن تعمل بشكل جيد!شكرا لكم جميعا على ردودكم!

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

المحلول

إذا كنت أفهم بشكل صحيح، أود أن أضيف جدول BoxItemTasks (مجرد جدول تعداد، أليس كذلك؟)، ثم جدول BoxItemActions مع مفاتيح خارجية إلى BoxItems وBoxItemTasks لنوع المهمة.إذا كنت تريد إجراء ذلك بحيث لا يمكن تنفيذ مهمة معينة إلا مرة واحدة على عنصر مربع معين، فما عليك سوى جعل زوج الأعمدة (العناصر + المهام) هو المفتاح الأساسي لـ BoxItemActions.

(لقد عرضتها بشكل أفضل بكثير مني، وأشكرك على تفسير ما كنت أقوله بشكل صحيح.ما كتبته هو بالضبط ما كنت أصوره.)

بالنسبة لتحديد الحالة الحالية، يمكنك كتابة مشغل على BoxItemActions يقوم بتحديث عمود واحد BoxItems.LastAction.بالنسبة للإجراءات المتزامنة، يمكن أن يحتوي المشغل الخاص بك على حالات خاصة فقط لتحديد الإجراء الذي سيكون أحدث.

نصائح أخرى

كما اقترحت الإجابة السابقة، أود أن أقسم طاولتك إلى عدة.

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

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

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

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

ثم في قاعدة البيانات الخاصة بك لديك بنية جدولين بسيطة.يقوم جدول BoxItems بتخزين بيانات BoxItem الأساسية الخاصة بك.ثم يشبه جدول BoxItemActions إلى حد كبير الحل الذي حددته كإجابة.

إنه مشابه بشكل أساسي للحل المقبول كإجابة، ولكن بدلاً من جدول BoxItemTasks لتخزين القائمة الرئيسية للمهام، يمكنك استخدام مستند XML الذي يسمح بمزيد من المرونة لتعريف سير العمل الفعلي.

على أية حال، في BizTalk يقومون "بتجفيف" أنماط الرسائل طويلة الأمد (سير العمل وما شابه) عن طريق إجراء تسلسل ثنائي لها في قاعدة البيانات.

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

بالنسبة لهذا النوع من المشاكل، فكر في مخطط قاعدة البيانات الموضح في http://www.databaseanswers.org/data_models/workflow/index.htm الذي يمثل سلسلة من الأحداث في عملية عمل.

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