मेरे पास एक ही संरचना वाले कई डेटाबेस हैं जिनमें कभी-कभी डेटा की प्रतिलिपि बनाई जाती है। डेटा अखंडता बनाए रखने के लिए मैं प्राथमिक कुंजी के रूप में दो कॉलम का उपयोग कर रहा हूं। एक डेटाबेस आईडी है, जो प्रत्येक डेटाबेस के बारे में जानकारी वाली तालिका से लिंक होता है। दूसरा एक टेबल कुंजी है। यह अद्वितीय नहीं है क्योंकि इसमें कई पंक्तियाँ हो सकती हैं जिनमें यह मान समान है, लेकिन डेटाबेस_आईडी कॉलम में अलग-अलग मान हैं।

मैं दो स्तंभों को एक संयुक्त प्राथमिक कुंजी बनाने की योजना बना रहा हूं। हालांकि मैं तालिका कुंजी को ऑटो वृद्धि में भी सेट करना चाहता हूं - लेकिन डेटाबेस_आईडी कॉलम के आधार पर।

ईजी, इस डेटा के साथ:

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 में इसे हासिल करने का सबसे अच्छा तरीका क्या है।

29
SystemicPlural 24 मार्च 2011, 11:32

2 जवाब

आप दो स्तंभ वाली प्राथमिक कुंजी unique और स्वतः-वृद्धि कुंजी primary बना सकते हैं।

1
ElonChan 16 मई 2017, 12:28

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;
0
Kanagavelu Sugumar 20 जुलाई 2018, 10:49