2009-12-29 14 views
10

मैं एक SQL तालिका बनाना चाहता हूं जिसमें डेटा की एन पंक्तियों से अधिक न हो। जब एक नई पंक्ति डाली जाती है, तो मैं सबसे पुरानी पंक्ति को नए के लिए स्थान बनाने के लिए हटा देता हूं।एसक्यूएल तालिका 0 रोलिंग पंक्तियों में रोलिंग पंक्तियां

क्या SQLite के भीतर इसे संभालने का एक सामान्य तरीका है?

इसे कुछ बाहरी (तृतीय पक्ष) कोड के साथ प्रबंधित करना चाहिए?

उत्तर

11

Alex' answer विस्तार करते हुए, और यह सोचते हैं आप एक incrementing, न दोहराई तालिका tserial नामित जो पंक्तियों की रिश्तेदार उम्र निर्धारित करने के लिए इस्तेमाल किया जा सकता पर सीरियल स्तंभ:

CREATE TRIGGER ten_rows_only AFTER INSERT ON t 
    BEGIN 
    DELETE FROM t WHERE serial <= (SELECT serial FROM t ORDER BY serial DESC LIMIT 10, 1); 
    END; 

यह आपको कम से कम दस पंक्तियों है, और सबसे कम धारावाहिक DELETE जब एक INSERT ग्यारह पंक्तियों को आप धक्का होगा होगा जब कोई कार्य नहीं करेगा।

अद्यतन

यहाँ थोड़ी ज्यादा जटिल मामला है, जहां अपनी मेज रिकॉर्ड एक स्तंभ जो डुप्लिकेट होते हैं, उदाहरण के लिए एक TIMESTAMP स्तंभ डालने बार ट्रैकिंग के रूप में हो सकता है में पंक्ति की "उम्र"।

sqlite> .schema t 
CREATE TABLE t (id VARCHAR(1) NOT NULL PRIMARY KEY, ts TIMESTAMP NOT NULL); 
CREATE TRIGGER ten_rows_only AFTER INSERT ON t 
    BEGIN 
    DELETE FROM t WHERE id IN (SELECT id FROM t ORDER BY ts DESC LIMIT 10, -1); 
    END; 

यहाँ हम दी गई है कि हम id उपयोग नहीं कर सकते रिश्तेदार उम्र का निर्धारण करने के लिए ले, तो हम पहले 10 पंक्तियों टाइमस्टैम्प द्वारा आदेशित के बाद सब कुछ को हटा दें। (SQLite उसी ts साझा करने वाली पंक्तियों पर एक मनमाने ढंग से आदेश लगाता है)।

+0

यह हमेशा पहली पंक्ति को नष्ट नहीं होगा सक्षम होना चाहिए? – aronchick

+0

@aronchick, नहीं - 11 वीं स्थिति (संभवतः 11 वीं पंक्ति के हमारे INSERT के बाद) में कोई रिकॉर्ड नहीं होने पर स्केलर सबक्वायरी एनयूएलएल का मूल्यांकन करेगा, और इसलिए 'WHERE' क्लॉज तब' सीरियल <= NULL' बन जाएगा, जो कुछ भी मेल नहीं खाएगा। – pilcrow

+0

क्या होगा यदि _id स्वतः बढ़ी है। क्या यह कोड TIMESTAMP या धारावाहिक के बजाय _id के साथ पूरा नहीं किया जा सका? विशेष रूप से जब एक टाइमस्टैम्प हमेशा तालिका स्कीमा का हिस्सा नहीं होता है ... –

0

यह ऐसा कुछ होगा जैसे आप इसे कैसे करेंगे। यह मानता है कि my_id_column स्वत: वृद्धिशील है और तालिका के लिए ऑर्डरिंग कॉलम है। एसक्यूएल में तय कतारों पर

-- handle rolls forward 
-- deletes the oldest row 
create trigger rollfwd after insert on my_table when (select count() from my_table) > max_table_size 
    begin 
    delete from my_table where my_id_column = (select min(my_id_column) from my_table); 
    end; 

-- handle rolls back 
-- inserts an empty row at the position before oldest entry 
-- assumes all columns option or defaulted 
create trigger rollbk after delete on my_table when (select count() from my_table) < max_table_size 
    begin 
    insert into my_table (my_id_column) values ((select min(my_id_column) from my_table) - 1); 
    end; 
संबंधित मुद्दे