سؤال

في وقت فراغي بدأت كتابة الصغيرة لعبة متعددة اللاعبين مع قاعدة بيانات الواجهة الخلفية.كنت تبحث منفصلة لاعب معلومات تسجيل الدخول من الأخرى في معلومات اللعبة (المخزون, احصائيات, مركز) و صديق ترعرعت هذا قد لا يكون أفضل فكرة.

سيكون من الأفضل أن تجمع كل شيء معا في طاولة واحدة?

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

المحلول

وتبدأ من خلال تجاهل الأداء، ومجرد إنشاء التصميم الأكثر منطقية وسهلة الفهم قاعدة البيانات التي يمكن. إذا اللاعبين والأشياء عبة (السيوف؟ قطع الشطرنج؟) أشياء منفصلة من الناحية النظرية، ثم وضعها في جداول منفصلة. إذا كان لاعب يمكن أن تحمل الأشياء، كنت وضعت المفتاح الخارجي في الجدول "الأشياء" يشير "اللاعبين" الجدول. وهلم جرا.

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

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

نصائح أخرى

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

وقال أنني أريد أن أذكر أن هناك واقع الحياة، أيضا ؛-). A علاقة واحد الى واحد <م> قد معنى، أي إذا كان عدد الأعمدة في الجدول يصل إلى مستوى حرج قد يكون أسرع لتقسيم هذا الجدول. ولكن هذا النوع من الظروف حقا نادرة.

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

<القوي> تقول إديث : لوتعليقا على التطبيع: حسنا، أنا لم ير قاعدة بيانات تطبيع إليه ماكس ولا أحد يوصي حقا أن كخيار. على أي حال، إذا كنت لا تعرف بالضبط ما اذا كان سيتم تطبيع أية أعمدة (أي وضع في جداول أخرى) في وقت لاحق، ثم هو أيضا أسهل أن تفعل هذا مع جدول واحد بدلا من "الجدول" -one إلى واحد- "الجدول الآخر "

ما إذا كان للحفاظ على

لاعب معلومات تسجيل الدخول [فصل] من أخرى في معلومات اللعبة (المخزون ، احصائيات ، وحالة)

وغالبا ما يكون مسألة التطبيع.قد ترغب في إلقاء نظرة سريعة على ويكيبيديا (النموذج العادي الثالث, Denormalization) التعاريف.إذا كنت تفصل هذه إلى جداول متعددة يعتمد على ما يتم تخزين البيانات.توسيع سؤالك سوف تجعل هذه الخرسانة.البيانات التي نريد أن المخزن هو:

  • اسم المستخدم:الاسم الفريد الذي يسمح للمستخدم تسجيل الدخول إلى النظام
  • passwd:كلمة المرور:يرتبط اسم المستخدم الذي يضمن المستخدم فريدة من نوعها
  • البريد الإلكتروني:عنوان البريد الإلكتروني المستخدم ؛ وبالتالي فإن لعبة يمكن أن "كزة" المستخدم عندما لم تكن قد لعبت مؤخرا
  • حرف:ربما منفصلة داخل اللعبة اسم الحرف
  • حالة:هو لاعب و/أو الطابع النشط حاليا
  • hitpoints:مثال على ذلك القانون الأساسي للحرف

ونحن يمكن تخزين هذا جدول واحد أو جداول متعددة.

جدول واحد على سبيل المثال

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

CREATE TABLE players(
  id         INTEGER NOT NULL,
  username   VARCHAR2(32) NOT NULL,
  password   VARCHAR2(32) NOT NULL,
  email      VARCHAR2(160),
  character  VARCHAR2(32) NOT NULL,
  status     VARCHAR2(32),
  hitpoints  INTEGER,

  CONSTRAINT pk_players PRIMARY KEY (uid)
);

هذا من شأنه أن تسمح لك للعثور على جميع المعلومات ذات الصلة عن لاعب مع استعلام واحد على اللاعبين الجدول.

متعددة الجدول سبيل المثال

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

-- track information on the player
CREATE TABLE players(
  id         INTEGER NOT NULL,
  username   VARCHAR2(32) NOT NULL,
  password   VARCHAR2(32) NOT NULL,
  email      VARCHAR2(160),

  CONSTRAINT pk_players PRIMARY KEY (id)
);

-- track information on the character
CREATE TABLE characters(
  id         INTEGER NOT NULL,
  player_id  INTEGER NOT NULL,
  character  VARCHAR2(32) NOT NULL,
  status     VARCHAR2(32),
  hitpoints  INTEGER,

  CONSTRAINT pk_characters PRIMARY KEY (id)
);
-- foreign key reference
ALTER TABLE characters
  ADD CONSTRAINT characters__players
  FOREIGN KEY (player_id) REFERENCES players (id);

هذا الشكل لا تتطلب ينضم عندما تبحث في المعلومات عن كل لاعب و الحرف ؛ ومع ذلك ، فإنه يجعل من تحديث سجلات أقل احتمالا أن يؤدي إلى التناقض.هذا الجدل الأخير يستخدم عادة عندما الدعوة إلى جداول متعددة.على سبيل المثال, إذا كان لديك لاعب (LotRFan) مع اثنين من الشخصيات (كونان, فرودو) في جدول واحد شكل سيكون لديك اسم المستخدم, كلمة المرور, البريد الإلكتروني الحقول المكررة.إذا كان لاعب يريد أن يغير البريد الإلكتروني/كلمة المرور, سوف تحتاج إلى تعديل كل السجلات.إذا سجل واحد فقط تم تعديل الجدول سوف تصبح غير متناسقة.ومع ذلك ، إذا LotRFan أردت تغيير كلمة المرور في عدة تنسيق الجدول صف واحد في جدول يتم تحديثه.

اعتبارات أخرى

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

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

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

ويمكنك أيضا أن يكون الاشياء الشخصية لكل مستخدم منفصل عن الاشياء العام (أي ما يمكن للآخرين أن نرى منكم). قد توفر أفضل ذاكرة التخزين المؤقت يضرب، لأن الكثير من الناس سوف نرى سمات العامة الخاصة بك، ولكن فقط ترى سمات الشخصية.

وعلاقة 1-1 هو مجرد انقسام العمودي. لا شيء آخر. تفعل ذلك إذا كنت لسبب أنك لن تخزين كافة البيانات في الجدول نفسه (ويقول لتقسيم عبر عدة ملقمات الخ)

كما يمكنك أن ترى, التوافق العام في الآراء هو أن "الأمر يتوقف".أداء/الاستعلام الأمثل بسهولة يتبادر إلى الذهن - كما ذكر من قبل @كامبل و بائعين آخرين.

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

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

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

أعتقد أفضل لتوضيح ما أعنيه سبيل المثال:

حالة 1:فئة واحدة / طاولة واحدة

هل تعتقد من حيث لاعب فئة.لاعب.مصادقة, لاعب.logged_in?, لاعب.وحالة اللاعب.hi_score, لاعب.gold_credits.طالما أن كل هذه الإجراءات على مستخدم واحد أو تمثل واحدة قيمة سمات المستخدم ، ثم جدول واحد يجب أن تكون نقطة البداية من المنطقي تطبيق منظور التصميم.صنف واحد (لاعب) ، جدول واحد (لاعبين).

الحالة 2:متعددة فئة / واحد أو أكثر من الجداول

ربما أنا لا أحب السويسري-سكين الجيش لاعب فئة التصميم ، ولكن يفضل أن نفكر في المستخدم, المخزون, اللوحة و الحساب.المستخدم.مصادقة المستخدم.logged_in?, المستخدم->الحساب.مركز اللوحة.hi_score(المستخدم) المستخدم->الحساب.gold_credits.

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

مما يجعل 'المثالي' العملية

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

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

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

كن حذرا عند التفكير في الأداء على الرغم من:فقط لأنه قد يكون صف واحد في جدول واحد ، ربما لا يعني أنه هو الاستعلام مرة واحدة فقط للحصول على الصف كله.أتصور متعددة لعبة السيناريو قد تنطوي على سلسلة كاملة من المكالمات للحصول على لاعب مختلف المعلومات في أوقات مختلفة, و اللاعب دائما يريد الحالية القيمة والتي قد تكون ديناميكية جدا.التي قد تترجم إلى العديد من يدعو إلى مجرد عدد قليل من الأعمدة في الجدول في كل مرة (في هذه الحالة ، متعددة-تصميم الجدول يمكن أن تكون أسرع من واحد-تصميم الجدول).

وأوصي تفصل بينها. ليس لأي أسباب قاعدة البيانات، ولكن لأسباب التنمية.

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

وانها تتلخص في حقيقة أن لعبة وحدة المعلومات الخاصة بك ليست حصلت على أي messin الأعمال "حولها مع طاولة لاعب تسجيل الدخول.

وربما كذلك لوضعها في جدول واحد في هذا الوضع بأنه أداء الاستعلام الخاص بك وسوف يكون أفضل.

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

وأنا أتفق مع توماس بادرون-مكارثي الجواب :

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

وكما انه من الجدير بالذكر أن المؤشرات يمكن النظر في الجداول كما منفصلة التي تحتوي على وجهة نظر أضيق من البيانات.

وقد

والناس قادرين على استنتاج التصميم المستخدمة في عاصفة ثلجية قوية لعلب من العالم. ويبدو أن المهام لاعب على تخزين مع الحرف. منها مثلا:

CREATE TABLE Players (
   PlayerID int,
   PlayerName varchar(50),
   ...
   Quest1ID int,
   Quest2ID int,
   Quest3ID int,
   ...
   Quest10ID int,
   ...
)

في البداية هل يمكن أن يكون باقل من 10 أسئلة، وبعد ذلك تم توسيعه إلى 25، منها مثلا:

CREATE TABLE Players (
   PlayerID int,
   PlayerName varchar(50),
   ...
   Quest1ID int,
   Quest2ID int,
   Quest3ID int,
   ...
   Quest25ID int,
   ...
)

وهذا هو على النقيض من تصميم الانقسام:

CREATE TABLE Players (
   PlayerID int,
   PlayerName varchar(50),
   ...
)

CREATE TABLE PlayerQuests (
   PlayerID int,
   QuestID int
)

وهذا الأخير هو أسهل بكثير من الناحية النظرية على التعامل معها، وأنه يسمح للعدد التعسفي من المهام. من ناحية أخرى كان لديك للانضمام لاعبين وPlayerQuests من أجل الحصول على كل تلك المعلومات.

وأود أن أقترح عليك أن تبقي كل نوع السجل في الجدول الخاص بها.

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

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