मेरे पास एक ही संरचना वाले कई डेटाबेस हैं जिनमें कभी-कभी डेटा की प्रतिलिपि बनाई जाती है। डेटा अखंडता बनाए रखने के लिए मैं प्राथमिक कुंजी के रूप में दो कॉलम का उपयोग कर रहा हूं। एक डेटाबेस आईडी है, जो प्रत्येक डेटाबेस के बारे में जानकारी वाली तालिका से लिंक होता है। दूसरा एक टेबल कुंजी है। यह अद्वितीय नहीं है क्योंकि इसमें कई पंक्तियाँ हो सकती हैं जिनमें यह मान समान है, लेकिन डेटाबेस_आईडी कॉलम में अलग-अलग मान हैं।
मैं दो स्तंभों को एक संयुक्त प्राथमिक कुंजी बनाने की योजना बना रहा हूं। हालांकि मैं तालिका कुंजी को ऑटो वृद्धि में भी सेट करना चाहता हूं - लेकिन डेटाबेस_आईडी कॉलम के आधार पर।
ईजी, इस डेटा के साथ:
table_id database_id other_columns
1 1
2 1
3 1
1 2
2 2
अगर मैं डेटा जोड़ रहा हूं जिसमें 1 का dabase_id शामिल है तो मैं चाहता हूं कि table_id स्वचालित रूप से 4 पर सेट हो जाए। यदि dabase_id 2 के रूप में दर्ज किया गया है तो मैं चाहता हूं कि table_id स्वचालित रूप से 3 पर सेट हो जाए। आदि।
MySQL में इसे हासिल करने का सबसे अच्छा तरीका क्या है।
2 जवाब
आप दो स्तंभ वाली प्राथमिक कुंजी unique
और स्वतः-वृद्धि कुंजी primary
बना सकते हैं।
DTing द्वारा प्रदान किया गया समाधान उत्कृष्ट और कार्यशील है। लेकिन जब एडब्ल्यूएस अरोड़ा में एक ही कोशिश की, यह काम नहीं किया और नीचे त्रुटि की शिकायत की।
Error Code: 1075. Incorrect table definition; there can be only one auto column and it must be defined as a key
इसलिए यहां जेसन आधारित समाधान का सुझाव दे रहे हैं।
CREATE TABLE DB_TABLE_XREF (
db VARCHAR(36) NOT NULL,
tables JSON,
PRIMARY KEY (db)
)
पहली प्राथमिक कुंजी बाहर, और दूसरी प्राथमिक कुंजी जोंस के अंदर रखें और दूसरी प्राथमिक कुंजी मान को auto_incr_sequence के रूप में बनाएं।
INSERT INTO `DB_TABLE_XREF`
(`db`, `tables`)
VALUES
('account_db', '{"user_info": 1, "seq" : 1}')
ON DUPLICATE KEY UPDATE `tables` =
JSON_SET(`tables`,
'$."user_info"',
IFNULL(`tables` -> '$."user_info"', `tables` -> '$."seq"' + 1),
'$."seq"',
IFNULL(`tables` -> '$."user_info"', `tables` -> '$."seq"' + 1)
);
और आउटपुट नीचे जैसा है
account_db {"user_info" : 1, "user_details" : 2, "seq" : 2}
product_db {"product1" : 1, "product2" : 2, "product3" : 3, "seq" : 3}
यदि आपकी माध्यमिक कुंजी बहुत बड़ी हैं, और जेसन का उपयोग करने से डरते हैं, तो मैं नीचे दिए गए लॉक के साथ MAX (सेकेंडरी_कॉलम) की जांच करने के लिए संग्रहीत प्रक्रिया का सुझाव दूंगा।
SELECT table_id INTO t_id FROM DB_TABLE_XREF WHERE database = db_name AND table = table_name;
IF t_id = 0 THEN
SELECT GET_LOCK(db_name, 10) INTO acq_lock;
-- CALL debug_msg(TRUE, "Acquiring lock");
IF acq_lock = 1 THEN
SELECT table_id INTO t_id FROM DB_TABLE_XREF WHERE database_id = db_name AND table = table_name;
-- double check lock
IF t_id = 0 THEN
SELECT IFNULL((SELECT MAX(table_id) FROM (SELECT table_id FROM DB_TABLE_XREF WHERE database = db_name) AS something), 0) + 1 into t_id;
INSERT INTO DB_TABLE_XREF VALUES (db_name, table_name, t_id);
END IF;
ELSE
-- CALL debug_msg(TRUE, "Failed to acquire lock");
END IF;
COMMIT;
संबंधित सवाल
जुड़े हुए प्रश्न
नए सवाल
mysql
MySQL एक फ्री, ओपन सोर्स रिलेशनल डेटाबेस मैनेजमेंट सिस्टम (RDBMS) है जो स्ट्रक्चर्ड क्वेरी लैंग्वेज (SQL) का उपयोग करता है। इस टैग को अन्य DBs जैसे SQL Server, SQLite आदि के लिए उपयोग न करें। वे विभिन्न DB हैं जो सभी डेटा का प्रबंधन करने के लिए SQL की अपनी बोलियों का उपयोग करते हैं।