سؤال

على سبيل المثال، يستخدم Google App Engine مخزن بيانات Google، وليس قاعدة بيانات قياسية، لتخزين البيانات.هل لدى أي شخص أي نصائح لاستخدام Google Datastore بدلاً من قواعد البيانات؟يبدو أنني قمت بتدريب عقلي على التفكير بنسبة 100% في علاقات الكائنات التي ترتبط مباشرة بهياكل الجدول، والآن من الصعب رؤية أي شيء بشكل مختلف.أستطيع أن أفهم بعض فوائد Google Datastore (على سبيل المثال.الأداء والقدرة على توزيع البيانات)، ولكن يتم التضحية ببعض وظائف قاعدة البيانات الجيدة (على سبيل المثال.ينضم).

هل لدى أي شخص عمل مع Google Datastore أو BigTable أي نصيحة جيدة للعمل معهم؟

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

المحلول

هناك شيئان رئيسيان يجب الاعتياد عليهما فيما يتعلق بمخزن بيانات App Engine عند مقارنته بقواعد البيانات العلائقية "التقليدية":

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

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

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

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

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

نصائح أخرى

الطريقة التي كنت أتبعها في التبديل العقلي هي نسيان قاعدة البيانات تمامًا.

في عالم قواعد البيانات العلائقية، عليك دائمًا أن تقلق بشأن تسوية البيانات وبنية الجدول الخاص بك.تخلص من كل شيء.مجرد تخطيط صفحة الويب الخاصة بك.ضعهم جميعًا.الآن أنظر إليهم.أنت بالفعل 2/3 هناك.

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

نعم، هذا شرح مبسط للمحنة، لكنه ساعدني على نسيان قواعد البيانات والقيام بالتطبيق فقط.لقد قمت بإنشاء 4 تطبيقات App Engine حتى الآن باستخدام هذه الفلسفة، وهناك المزيد في المستقبل.

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

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

بلدي اثنين بنسا.


class League(BaseModel):
    name = db.StringProperty()    
    managers = db.ListProperty(db.Key) #all the users who can view/edit this league
    coaches = db.ListProperty(db.Key) #all the users who are able to view this league

    def get_managers(self):
        # This returns the models themselves, not just the keys that are stored in teams
        return UserPrefs.get(self.managers)

    def get_coaches(self):
        # This returns the models themselves, not just the keys that are stored in teams
        return UserPrefs.get(self.coaches)      

    def __str__(self):
        return self.name

    # Need to delete all the associated games, teams and players
    def delete(self):
        for player in self.leagues_players:
            player.delete()
        for game in self.leagues_games:
            game.delete()
        for team in self.leagues_teams:
            team.delete()            
        super(League, self).delete()

class UserPrefs(db.Model):
    user = db.UserProperty()
    league_ref = db.ReferenceProperty(reference_class=League,
                            collection_name='users') #league the users are managing

    def __str__(self):
        return self.user.nickname

    # many-to-many relationship, a user can coach many leagues, a league can be
    # coached by many users
    @property
    def managing(self):
        return League.gql('WHERE managers = :1', self.key())

    @property
    def coaching(self):
        return League.gql('WHERE coaches = :1', self.key())

    # remove all references to me when I'm deleted
    def delete(self):
        for manager in self.managing:
            manager.managers.remove(self.key())
            manager.put()
        for coach in self.managing:
            coach.coaches.remove(self.key())
            coaches.put()            
        super(UserPrefs, self).delete()    

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

لا بد أنك تعلم بالفعل أن Datastore مصمم على نطاق واسع وهذا هو الشيء الذي يفصله عن RDMBS.للتوسع بشكل أفضل باستخدام مجموعة البيانات الكبيرة، أجرى App Engine بعض التغييرات (بعضها يعني الكثير من التغييرات).

RDBMS مقابل مخزن البيانات
بناء
في قاعدة البيانات، نقوم عادةً بتنظيم بياناتنا في الجداول والصفوف الموجودة في Datastore أنواع وكيانات.

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

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

عدد
في RDMBS، يكون العد (*) أسهل بكثير ولكن في مخزن البيانات، من فضلك لا تفكر في الأمر بالطريقة العادية (نعم هناك وظيفة العد) كما هو الحال 1000 الحد وسوف تكلف نفس القدر عملية صغيرة ككيان ليس جيدًا ولكن لدينا دائمًا خيارات جيدة يمكننا استخدامها عدادات شارد.

القيود الفريدة
في RDMBS، نحن نحب هذه الميزة، أليس كذلك؟لكن Datastore له طريقته الخاصة.لا يمكنك تحديد خاصية على أنها فريدة :(.

استفسار
يوفر GAE Datatore ميزة أفضل كثيرًا يحب(أوه لا!لا يحتوي مخزن البيانات على LIKE Keyword) SQL وهو جي كيو إل.

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

ألق نظرة على وثائق Objectify.يقول التعليق الأول في أسفل الصفحة:

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

https://github.com/objectify/objectify/wiki/Concepts

إذا كنت معتادًا على التفكير في الكيانات المعينة بواسطة ORM، فهذه هي الطريقة الأساسية التي يعمل بها مخزن البيانات المستند إلى الكيان مثل محرك التطبيقات من Google.لشيء مثل الانضمام، يمكنك إلقاء نظرة على الخصائص المرجعية.لا داعي للقلق حقًا بشأن ما إذا كان يستخدم BigTable للواجهة الخلفية أو أي شيء آخر نظرًا لأن الواجهة الخلفية يتم تجريدها بواسطة واجهات GQL وDatastore API.

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

بالعودة الآن إلى التعليق الأصلي، فإن مخزن بيانات Google وBigtable شيئان مختلفان، لذا لا تخلط بين مخزن بيانات Google ومعنى تخزين بيانات مخزن البيانات.Bigtable أغلى من BigQuery (السبب الرئيسي لعدم موافقتنا عليه).لدى Bigquery صلات مناسبة ونظام RDBMS مثل لغة SQL وأرخص، فلماذا لا تستخدم BigQuery.ومع ذلك، فإن BigQuery لديه بعض القيود، اعتمادًا على حجم بياناتك التي قد تواجهها أو لا تواجهها.

أيضًا، فيما يتعلق بالتفكير فيما يتعلق بمخزن البيانات، أعتقد أن العبارة المناسبة ستكون "التفكير فيما يتعلق بقواعد بيانات NoSQL".هناك الكثير منها متاح هذه الأيام ولكن عندما يتعلق الأمر بمنتجات Google باستثناء google cloud SQL (وهو mySQL) فإن كل شيء آخر هو NoSQL.

نظرًا لكونه متجذرًا في عالم قواعد البيانات، فإن مخزن البيانات بالنسبة لي سيكون عبارة عن جدول عملاق (ومن هنا جاء اسم "bigtable").تعد BigTable مثالًا سيئًا لأنها تقوم بالكثير من الأشياء الأخرى التي قد لا تقوم بها قاعدة البيانات النموذجية، ومع ذلك فهي لا تزال قاعدة بيانات.من المحتمل أنه ما لم تكن تعلم أنك بحاجة إلى إنشاء شيء مثل "الجدول الكبير" الخاص بـ Google، فمن المحتمل أن تكون جيدًا مع قاعدة البيانات القياسية.إنهم بحاجة إلى ذلك لأنهم يتعاملون مع كميات هائلة من البيانات والأنظمة معًا، ولا يمكن لأي نظام متاح تجاريًا القيام بالمهمة بالطريقة الدقيقة التي يمكنهم من خلالها إثبات أنهم بحاجة إلى إنجاز المهمة.

(مرجع كبير: http://en.wikipedia.org/wiki/BigTable)

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