2012-10-31 8 views
5

मेरे पास आपके लोगों के लिए स्क्लेक्लेमी, डेटाबेस शेरिंग और यूयूआईडी से संबंधित एक प्रश्न है। इस मेज पर एक छोटी सी पृष्ठभूमिएसक्लाक्लेमी, यूयूआईडी, शेरिंग, और ऑटोऑक्रिकमेंट प्राथमिक कुंजी ... उन्हें एक साथ काम करने के लिए कैसे प्राप्त करें?

CREATE TABLE foo (
    added_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, 
    id BINARY(16) NOT NULL, 
    ... other stuff ... 
    UNIQUE KEY(id) 
); 

:

मैं वर्तमान में MySQL का उपयोग कर रहा है, जिसमें मैं फार्म की एक मेज है। मुझे 'add_id' की परवाह नहीं है, मैं केवल यह सुनिश्चित करने के लिए उपयोग कर रहा हूं कि डाले गए आइटम डिस्क पर एक साथ क्लस्टर किए गए हैं (चूंकि My -QL में तालिका को इंडेक्स करने के लिए उपयोग किए जाने वाले बी-ट्री क्लस्टर इंडेक्स के रूप में प्राथमिक कुंजी का उपयोग करता है)। 'आईडी' कॉलम में यूयूआईडी का द्विआधारी प्रतिनिधित्व होता है - यह वह स्तंभ है जिसे मैं वास्तव में परवाह करता हूं और अन्य सभी चीजें इस आईडी को संदर्भित करती हैं। दोबारा, मैं नहीं चाहता कि यूयूआईडी प्राथमिक कुंजी हो, क्योंकि यूयूआईडी यादृच्छिक है और इस प्रकार तालिका को इंडेक्स करने के लिए बनाए गए बी-ट्री को भयानक आईओ विशेषताओं (कम से कम यही कहा गया है)। इसके अलावा, यद्यपि यूयूआईडी 1 में यह सुनिश्चित करने के लिए टाइमस्टैम्प शामिल है कि आईडी "अनुक्रमिक" क्रम में उत्पन्न होती है, आईडी में मैक पते को शामिल करने से यह कुछ ऐसा होता है जिसे मैं टालना चाहता हूं। इस प्रकार, मैं UUID4s का उपयोग करना चाहता हूं।

ठीक है, अब SQLAlchemy भाग पर आगे बढ़ रहा है। SQLAlchemy में से एक की तरह कुछ कर रही द्वारा एक मॉडल उपरोक्त तालिका के लिए अपने ORM का उपयोग कर परिभाषित कर सकते हैं:

# The SQL Alchemy ORM base class 
Base = declerative_base() 

# The model for table 'foo' 
class Foo(Base): 
    __table__ = 'foo' 
    add_id = Column(Integer, primary_key=True, nullable=False) 
    id = Column(Binary, index=True, unique=True, nullable=False) 
    ... 

फिर, यह मूल रूप से ऊपर एसक्यूएल के समान है।

और अब सवाल के लिए। आइए मान लें कि यह डेटाबेस 2 (या अधिक) अलग डेटाबेस में sharded (क्षैतिज रूप से विभाजित) जा रहा है। अब, (कोई विलोपन नहीं माना जाता है) इनमें से प्रत्येक डेटाबेस में तालिका foo में 1, 2, 3, आदि के add_id के साथ रिकॉर्ड होंगे। चूंकि SQLAlchemy उन ऑब्जेक्ट्स को प्रबंधित करने के लिए एक सत्र का उपयोग करता है जो इस पर काम कर रहे हैं कि प्रत्येक ऑब्जेक्ट को केवल इसकी प्राथमिक कुंजी द्वारा पहचाना जाता है, ऐसा लगता है कि ऐसी स्थिति हो सकती है जहां मैं दो फू ऑब्जेक्ट्स को दो से एक्सेस करने का प्रयास कर सकता हूं उसी add_id के साथ shards जिसके परिणामस्वरूप प्रबंधित सत्र में कुछ संघर्ष हुआ।

क्या कोई इस मुद्दे पर चलता है? इसे हल करने के लिए आपने क्या किया है? या, संभावना से अधिक, क्या मुझे स्क्लेक्लेमी दस्तावेज से कुछ याद आ रहा है जो सुनिश्चित करता है कि ऐसा नहीं हो सकता है। हालांकि, SQLAlchemy डाउनलोड (उदाहरण/sharding/attribute_shard.py) के साथ प्रदान किए गए चौंकाने वाले उदाहरण को देखते हुए वे एक आईडी जनरेटर के रूप में डेटाबेस शॉर्ड्स में से एक को नामित करके इस समस्या को साइड-चरण करते हैं ... सभी के रूप में एक अंतर्निहित बोतल गर्दन बनाना आईडी प्राप्त करने के लिए INSERTS को उस एकल डेटाबेस के विरुद्ध जाना होगा। (वे यूयूआईडी का उपयोग करने का भी उल्लेख करते हैं, लेकिन जाहिर है कि इंडेक्स के लिए प्रदर्शन समस्या का कारण बनता है।)

वैकल्पिक रूप से, यूयूआईडी को प्राथमिक कुंजी के रूप में सेट करने का तरीका है और डेटा को add_id का उपयोग करके डिस्क पर क्लस्टर किया गया है? यदि MySQL में यह संभव नहीं है तो क्या यह पोस्टग्रेज़ की तरह किसी अन्य डीबी में संभव है?

किसी भी और सभी इनपुट के लिए अग्रिम धन्यवाद!

--- अद्यतन ---- मैं सिर्फ इस प्रश्न से प्राप्त बैंड उत्तर से बाहर निकलना चाहता हूं। निम्नलिखित पाठ कुछ मैंने लिखा नहीं है, अगर मैं इसे उपयोगी पाता हूं तो मैं इसे यहां शामिल करना चाहता हूं।

MySQL और ऑटो वृद्धि कुंजी के साथ उस स्थिति से बचने का सबसे आसान तरीका प्रत्येक डेटाबेस के लिए अलग-अलग ऑटो वृद्धि ऑफ़सेट का उपयोग करना है, उदा।:

वैकल्पिक तालिका foo AUTO_INCREMENT = 100000;

नकारात्मकता यह है कि आपको प्रत्येक शार्ड को कॉन्फ़िगर करने के तरीके की देखभाल करने की आवश्यकता है, और आपको उपयोग की जाने वाली शर्ड्स की कुल संख्या को थोड़ा सा प्लॉट करने की आवश्यकता है।

क्लस्टर्ड इंडेक्स के लिए गैर-प्राथमिक कुंजी का उपयोग करने के लिए MySQL को मनाने का कोई तरीका नहीं है। यदि आपको अपने डेटाबेस स्कीमा को प्रबंधित करने के लिए SQLAlchemy का उपयोग करने की परवाह नहीं है (हालांकि, आपको शायद चाहिए), तो आप आसानी से UUID को SQLAlchemy स्कीमा में प्राथमिक कुंजी के रूप में सेट कर सकते हैं और वास्तविक तालिका में add_id को pk के रूप में छोड़ सकते हैं।

मैंने वैकल्पिक समाधान भी देखा है जो पंक्ति आईडी को बनाए रखने के लिए बाहरी सर्वर (उदा। रेडिस) का उपयोग करते हैं।

उत्तर

5

हां, तो आप मानचित्रण "primary_key" नक्शाकार तर्क है, जो या स्तंभ वस्तुओं की एक सूची के लिए एक एकल स्तंभ है का उपयोग कर के प्रयोजनों के लिए प्राथमिक कुंजी के रूप तालिका के स्तंभों में से किसी निर्दिष्ट कर सकते हैं:

Base = declarative_base() 

# The model for table 'foo' 
class Foo(Base): 
    __table__ = 'foo' 
    add_id = Column(Integer, primary_key=True, nullable=False) 
    id = Column(Binary, index=True, unique=True, nullable=False) 

    __mapper_args__ = {'primary_key': id} 

ऊपर, जबकि SQLAlchemy कोर "add_id" को "autoincrement" कॉलम के रूप में मानता है, तो मैपर को "आईडी" का उपयोग करने के बजाय अधिकतर इसमें रुचि नहीं होगी, क्योंकि ऑब्जेक्ट की "पहचान" पर विचार करते समय कॉलम की परवाह है ।

अधिक जानकारी के लिए documentation for mapper() देखें।

+0

धन्यवाद एक लाख। – prschmid

संबंधित मुद्दे