SQLite INSERT - डुप्लीकेट कुंजी पर अद्यतन (UPSERT)


98

MySQL में कुछ ऐसा है:

INSERT INTO visits (ip, hits)
VALUES ('127.0.0.1', 1)
ON DUPLICATE KEY UPDATE hits = hits + 1;

जहाँ तक मुझे पता है कि यह विशेषता SQLite में मौजूद नहीं है, तो मैं जानना चाहता हूँ कि क्या दो प्रश्नों के निष्पादन के बिना एक ही प्रभाव को प्राप्त करने का कोई तरीका है। इसके अलावा, यदि यह संभव नहीं है, तो आप क्या पसंद करते हैं:

  1. Select + (INSERT या UPDATE) या
  2. अद्यतन (+ अद्यतन विफल रहता है तो अद्यतन )

जवाबों:


31

चूंकि 3.24.0 SQLite भी मुखर समर्थन करता है , इसलिए अब आप केवल निम्नलिखित लिख सकते हैं

INSERT INTO visits (ip, hits)
VALUES ('127.0.0.1', 1)
ON CONFLICT(ip) DO UPDATE SET hits = hits + 1;

3
मैं सोच रहा था कि क्या आप upsertइस तरह के एक लेनदेन में कई कर सकते हैं , अर्थात् पायथन executemany()फ़ंक्शन के साथ?
रेडियो ने

117
INSERT OR IGNORE INTO visits VALUES ($ip, 0);
UPDATE visits SET hits = hits + 1 WHERE ip LIKE $ip;

इसके लिए "ip" कॉलम के लिए एक UNIQUE (या PRIMARY KEY) अवरोध की आवश्यकता होती है।


संपादित करें: एक अन्य महान समाधान: https://stackoverflow.com/a/4330694/89771


2
सिर्फ रिकॉर्ड के लिए, REPLACEएक विकल्प नहीं है।
एलिक्स एक्सल

1
"एक और महान समाधान" लिंक के बारे में, मैं एक ही प्रश्न के एक अलग उत्तर पर भी विचार करूंगा: stackoverflow.com/a/418988/3650835
कायकिनकोडर

19

मैं पसंद करूंगा UPDATE (+ INSERT if UPDATE fails)। कम कोड = कम कीड़े।


1
धन्यवाद! @Sam ( stackoverflow.com/questions/418898/… ) आपसे सहमत लगती है। मैं भी इस दृष्टिकोण को पसंद करता हूं।
एलिक्स एक्सल

@ मेरे पास सादा UPDATE और INSERT कथनों का उपयोग करने और वापसी मान की जाँच करने का मतलब है।
कोडहोलिक

इसमें एटमॉसिटी नहीं है यह संभव है कि अगर कुछ अन्य प्रक्रिया को बीच में डाला जाए तो INSERT विफल हो जाएगा।
रोबिन लावल्ली

7

वर्तमान उत्तर केवल sqlite या mysql में काम करेगा (यह निर्भर करता है कि आप OR या उपयोग करते हैं)। तो, अगर आप चाहते हैं क्रॉस dbms संगतता, निम्नलिखित करेंगे ...

REPLACE INTO `visits` (ip, value) VALUES ($ip, 0);

3
SQLite पर स्वीकृत उत्तर काम करता है (यह मेरा उद्देश्य था)। REPLACESQLite पर भी काम करेगा, लेकिन MySQL पर यह हमेशा काउंटर को 0 पर रीसेट करेगा - जबकि क्वेरी पोर्टेबल होगी, अंतिम परिणाम बहुत भिन्न होगा।
एलिक्स एक्सल

आप सही कह रहे हैं, मुझे लगा कि ओपी पोर्टेबल है। मुझे एहसास है कि INTO सभी मामलों के साथ काम नहीं करेगा, जहां पीके संरक्षण की जरूरत है, लेकिन कई मामलों के लिए होगा।
जैकब थॉमसन

डेटा को छोड़ने के बजाए सफाई से फेल होना एक विशेषता है, बग नहीं।
तोबू

-4

आपको इसके लिए मेम्केड का उपयोग करना चाहिए क्योंकि यह एक एकल कुंजी (IP पता) एक एकल मान (विज़िट की संख्या) को संग्रहीत करता है। आप परमाणु वेतन वृद्धि फ़ंक्शन का उपयोग यह सुनिश्चित करने के लिए कर सकते हैं कि कोई "दौड़" स्थितियां नहीं हैं।

यह MySQL से अधिक तेज़ है और लोड को बचाता है इसलिए MySQL अन्य चीजों पर ध्यान केंद्रित कर सकता है।


यदि डेटा इतना महत्वपूर्ण नहीं है, तो हाँ। हालाँकि, यदि इसका उपयोग किसी व्यस्त साइट पर किया जा रहा है, जहाँ कई IP सेवा से टकरा रहे हैं, तो संचित उदाहरण (s) पूर्ण हो सकते हैं और कुछ सामग्री को गिरा सकते हैं। यादगार सामग्री का बैकअप लेना भी दिलचस्प होगा (यदि आवश्यक हो।)
इलियट फोस्टर

@ElliotFoster Memcached रैम को जितना डेटा आप इसे फेंकते हैं उतना ही संभाल सकते हैं (यदि आप दृढ़ता भी चाहते हैं तो रेडिस या मेम्बेस का उपयोग करें)। यदि आप 1 मिलियन से अधिक आगंतुकों का दिन पा रहे हैं, तो आप संभवतः 30 एमबी से अधिक रैम (जो मुझे लगता है कि डिफ़ॉल्ट है) से अधिक अपने मेमेचे का उदाहरण दे सकते हैं। हालाँकि, यह निश्चित रूप से आपके द्वारा दी गई मेमोरी की मात्रा के लिए SQLite और MySQL की तुलना में बहुत अधिक भार को संभाल सकता है - कोई तुलना नहीं है।
Xeoncross

कृपया मेरी टिप्पणी को मेकचे के खिलाफ वोट के रूप में गलत न करें, क्योंकि मुझे लगता है कि यह एक शानदार उपकरण है। जैसा कि रेडिस है (मैं झिल्ली के लिए बात नहीं कर सकता, जैसा कि मैंने इसका उपयोग नहीं किया है।) हालांकि, मेमेचे / रेडिस सबसे विश्वसनीय स्टोर नहीं हैं। हां, रेडिस में दृढ़ता है, लेकिन डेटा एक अंतराल पर डिस्क के लिए बनी हुई है (आखिरी बार मैंने देखा था) और मेम्शे बिल्कुल नहीं। जैसा मैंने कहा, यदि डेटा महत्वपूर्ण नहीं है (या आसानी से पुन: पेश किया जा सकता है) तो मेमेचे और कंपनी महान हैं। मूल पोस्ट भी sqlite के बारे में पूछ रहा था, जो MySQL से बहुत अलग है और संभावना है कि वे अन्य तरीकों से सीमित हैं।
इलियट फोस्टर

आप डेटा को लगातार बनाए रखने के लिए Redis को कॉन्फ़िगर कर सकते हैं जैसे आप चाहते हैं (सेकंड के X नंबर या Y नंबर पर)।
भैंस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.