كيف يمكنك تصميم مخزن بيانات AppEngine لموقع اجتماعي مثل Twitter؟

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

سؤال

أتساءل ما الذي يمكن أن يكون أفضل طريقة لتصميم تطبيق اجتماعي حيث يقوم الأعضاء بعمل أنشطة ومتابعة أنشطة الأعضاء الآخرين باستخدام Google Appengine.

أن نكون أكثر تحديدًا ، لنفترض أن لدينا هذه الكيانات:

  • المستخدمون الذين لديهم أصدقاء
  • أنشطة التي تمثل الإجراءات التي يقوم بها المستخدمون (دعنا نقول أن لكل منها رسالة سلسلة ومرجعية لمستخدم مالكها ، أو يمكنه استخدام Association Association عبر مفتاح Appengine)

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

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

  • الحصول على "جميع المستخدمين الذين يتبعون X" هو استعلام محتمل AppEngine
  • ليست إدخال دفعة مكلفة للغاية في كيان "صندوق الوارد" الجديد الذي يخزن بشكل أساسي (المستخدم ، مفتاح النشاط).

سأكون سعيدًا لسماع التفكير في هذا التصميم أو الاقتراحات البديلة وما إلى ذلك.

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

المحلول

ألق نظرة على بناء تطبيقات قابلة للتطوير ومعقدة على محرك التطبيق (بي دي إف) ، حديث رائع قدم في Google I/O بواسطة Brett Slatkin. إنه يعالج مشكلة بناء خدمة مراسلة قابلة للتطوير مثل Twitter.

ها هو له المحلول باستخدام خاصية قائمة:

class Message(db.Model):
    sender = db.StringProperty()
    body = db.TextProperty()

class MessageIndex(db.Model):
    #parent = a message
    receivers = db.StringListProperty()

indexes = MessageIndex.all(keys_only = True).filter('receivers = ', user_id)
keys = [k.parent() for k in indexes)
messages = db.get(keys)

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

هنا الطريقة الخاطئة للقيام بذلك:

class Message(db.Model):
    sender = db.StringProperty()
    receivers = db.StringListProperty()
    body = db.TextProperty()

messages = Message.all().filter('receivers =', user_id)

هذا غير فعال لأن الاستفسارات يجب أن تضعف جميع النتائج التي تم إرجاعها عن طريق استعلامك. لذا ، إذا قمت بإرجاع 100 رسالة مع 1000 مستخدم في كل قائمة استقبال ، فسيتعين عليك إلغاء تمييز 100000 (100 × 1000) قيم خاصية قائمة. طريقة باهظة الثمن في زمن انتقال مخزن البيانات و CPU.

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

نصائح أخرى

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

انظر القسم الممثلين والنمور والدببة ، يا بلدي! في Design_funument.txt. يتم تعريف الكيانات في المشترك/النماذج والاستعلامات في مشترك/api.py.

روبرت ، حول الحل المقترح:

messages = Message.query(Message.receivers == user_id).fetch(projection=[Message.body])

أعتقد أنه لا يمكن استخدام NDB.TextProperty "الجسم" مع التوقعات لأنه لم يتم فهرسته. الإسقاطات تدعم فقط الخصائص المفهرسة. سيكون الحل الصحيح هو الحفاظ على الجداول 2: Message و MessageIndex.

أعتقد أن هذا يمكن حله الآن مع استعلامات الإسقاط الجديدة في NDB.

class Message(ndb.Model):
    sender = ndb.StringProperty()
    receivers = ndb.StringProperty(repeated=True)
    body = ndb.TextProperty()

messages = Message.query(Message.receivers == user_id).fetch(projection=[Message.body])

الآن ليس عليك التعامل مع التكلفة الباهظة للتخلص من خاصية القائمة.

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