फ्लैट फ़ाइल डेटाबेस [बंद]


120

PHP में फ्लैट फ़ाइल डेटाबेस स्ट्रक्चर्स बनाने के आसपास के सबसे अच्छे अभ्यास क्या हैं?

अधिक परिपक्व PHP फ्लैट फ़ाइल रूपरेखाओं में से एक है जो मैं SQL- जैसे क्वेरी सिंटैक्स को लागू करने का प्रयास करता हूं जो कि ज्यादातर मामलों में मेरे उद्देश्यों के लिए शीर्ष पर है। (मैं बस उस बिंदु पर एक डेटाबेस का उपयोग करेगा)।

क्या छोटे कोड ओवरहेड के साथ अच्छा प्रदर्शन और सुविधाएँ प्राप्त करने के लिए कोई सुंदर चाल है?


1
मैं जोड़ने के लिए एक पैकेज के लिए यहाँ है कि वहाँ चाहें फ्लैट फ़ाइल डेटाबेस github.com/tmarois/Filebase मैं जानता हूँ कि यह एक पुराने सवाल है, लेकिन इस पैकेज सबसे हाल ही में निर्माण और रख-रखाव, के साथ साथ है सुविधाओं का पूरा सबसे उपेक्षा शामिल करने के लिए ।
ताम्रिस

मैं एक CMS विकसित कर रहा हूं और मैं एक फ्लैट टेक्स्ट फाइल टेक्स्ट डेटाबेस का उपयोग करता हूं। इसे बनाने में कई घंटे लगते हैं और कई घंटे लगाने में लेकिन यह पूरी तरह से काम करता है। पूरी तरह से अनुक्रमित और अनुकूलित डेटाबेस के साथ क्वेरीज़ को बहुत तेज़ी से निष्पादित किया जाएगा। हालांकि, मैं मेटा डेटा संग्रहीत करके और सावधानीपूर्वक संगठन और संरचना से प्रश्नों की आवश्यकता से बचता हूं। जब मुझे डेटा की आवश्यकता होती है, तो मैं इसे बिना for loop(जब तक कि मैं फ़ोल्डर में सभी डेटा का उपयोग नहीं कर रहा हूं) प्राप्त कर लेता हूं, इसलिए यह डेटाबेस की तुलना में बहुत तेज प्रदर्शन करता है। मैं विस्तार में जाऊंगा और बहुत अच्छा जवाब दूंगा लेकिन दुर्भाग्य से यह सवाल बंद है।
डेन ब्रे

जवाबों:


75

खैर, फ्लैट डेटाबेस की प्रकृति क्या है। क्या वे बड़े या छोटे हैं। क्या यह उन में सरणियों के साथ सरल arrays है? अगर कुछ सरल कहना है कि इस तरह से बनाया गया

$user = array("name" => "dubayou", 
              "age" => 20,
              "websites" => array("dubayou.com","willwharton.com","codecream.com"),
              "and_one" => "more");

और उस उपयोगकर्ता के लिए db रिकॉर्ड को बचाने या अद्यतन करने के लिए।

$dir = "../userdata/";  //make sure to put it bellow what the server can reach.
file_put_contents($dir.$user['name'],serialize($user));

और उपयोगकर्ता के लिए रिकॉर्ड लोड करने के लिए

function &get_user($name){
    return unserialize(file_get_contents("../userdata/".$name));
}

लेकिन फिर से यह कार्यान्वयन आपके द्वारा आवश्यक डेटाबेस के अनुप्रयोग और प्रकृति पर भिन्न होगा।


48

आप SQLite पर विचार कर सकते हैं । यह लगभग सपाट फ़ाइलों की तरह सरल है, लेकिन आपको क्वेरी के लिए SQL इंजन मिलता है। यह PHP के साथ भी अच्छा काम करता है।


6
SQLite डिफ़ॉल्ट रूप से 5.0+ में निर्मित किया गया था, लेकिन PHP 5.4+ से छूट (!) पर !!! जैसा कि मैंने जुलाई 2012 में लिखा था, SQLite डिफ़ॉल्ट रूप से अप-टू-डेट सिस्टम पर काम नहीं करेगा। आधिकारिक बयान यहाँ
श्लिक

यदि आपके पास सर्वर एक्सेस है, तो SQLite PDO ड्राइवर स्थापित करना बहुत मामूली है। उबंटू / डेबियन में
अपाचे

4
@ स्लीक की टिप्पणी पर प्रतिक्रिया में, यह कहते हुए कि "SQLite था ... बंद किया गया" सत्य की तरह है: "SQLite" नाम का एक्सटेंशन बंद कर दिया गया था और "SQLite3" अब डिफ़ॉल्ट रूप से सक्षम है। php.net/manual/en/sqlite.installation.php "PHP 5.0 के बाद से यह एक्सटेंशन PHP के साथ बंद कर दिया गया था। PHP 5.4 के साथ शुरू होने पर, यह एक्सटेंशन केवल PECL के माध्यम से उपलब्ध है।" php.net/manual/en/sqlite3.installation.php " PHP 5.3 के रूप में SQLite3 एक्सटेंशन डिफ़ॉल्ट रूप से सक्षम है।" "यह विस्तार संक्षेप में एक पीईसीएल विस्तार था लेकिन यह संस्करण केवल प्रयोगात्मक उपयोग के लिए अनुशंसित है।"
पॉल वैन लीउवेन

आपने इस प्रश्न का उत्तर नहीं दिया
JG Estiot

20

मेरी राय में, "फ्लैट फाइल डेटाबेस" का उपयोग इस अर्थ में करें कि आप अर्थ (और आपके द्वारा स्वीकार किया गया उत्तर) चीजों के बारे में जाने का सबसे अच्छा तरीका नहीं है। सबसे पहले, का उपयोग कर serialize()औरunserialize() अगर किसी में हो जाता है और फ़ाइल को संपादित करता प्रमुख सिर दर्द पैदा कर सकता है (वे कर सकते हैं, वास्तव में, arbritrary कोड अपने "डेटाबेस" में हर बार चलाने के लिए डाल दिया।)

व्यक्तिगत रूप से, मैं कहूंगा - भविष्य के लिए क्यों नहीं? कई बार ऐसा हुआ है कि मेरे पास समस्याएं हैं क्योंकि मैं अपनी "मालिकाना" फाइलें बना रहा हूं, और परियोजना एक ऐसे बिंदु पर पहुंच गई है जहां इसे डेटाबेस की आवश्यकता है, और मैं सोच रहा हूं "आप जानते हैं, मैं चाहता हूं मैंने इसे एक डेटाबेस के साथ शुरू करने के लिए लिखा था "- क्योंकि कोड की रीफैक्टरिंग में बहुत अधिक समय और प्रयास लगता है।

इससे मुझे पता चला है कि भविष्य में मेरे आवेदन को प्रमाणित करना है ताकि जब यह बड़ा हो जाए तो मुझे जाने की जरूरत नहीं है और दिन बिताने का तरीका आगे बढ़ने का रास्ता है। मैं यह कैसे करु?

SQLite। यह एक डेटाबेस के रूप में काम करता है, SQL का उपयोग करता है, और mySQL में बदलना बहुत आसान है (यदि आप डेटाबेस हेरफेर के लिए अमूर्त वर्ग का उपयोग कर रहे हैं जैसे मैं करता हूं!)

वास्तव में, "स्वीकार किए गए उत्तर" विधि के साथ जासूसी करते हुए, यह आपके ऐप के मेमोरी उपयोग में भारी कटौती कर सकता है (आपको सभी "रिकॉर्ड" को PHP में लोड करने की आवश्यकता नहीं है)


यह सच है। serialize()उस के लिए भी बहुत उपयोगी हो सकता है। मुझे लगता है कि एक व्यवहार्य प्रणाली के साथ आने की चाल खुद को जटिलता के साथ मारे बिना डेटा नोड्स को इंडेक्स करने का कोई तरीका ढूंढ रही है।
संत_ग्रोसन

12

एक रूपरेखा जो मैं विचार कर रहा हूं वह एक ब्लॉगिंग प्लेटफॉर्म के लिए होगी। चूँकि डेटा के किसी भी संभावित दृष्टिकोण के बारे में आप चाहते हैं कि वह तिथि के अनुसार क्रमबद्ध हो जाए, मैं इस संरचना के बारे में सोच रहा था:

सामग्री नोड प्रति एक निर्देशिका:

./content/YYYYMMDDHHMMSS/

सहित प्रत्येक नोड के उपनिर्देशिका

/tags  
/authors  
/comments  

प्री-और पोस्ट-रेंडर किए गए कंटेंट और जैसे के लिए नोड डायरेक्टरी में सरल टेक्स्ट फाइलें।

यह एक साधारण PHP glob()कॉल (और शायद परिणाम सरणी का एक उलट) को सामग्री संरचना के भीतर किसी भी चीज़ पर क्वेरी करने की अनुमति देगा :

glob("content/*/tags/funny");  

"मजेदार" टैग किए गए सभी लेखों सहित वापसी के रास्ते चाहते हैं।


9

यहाँ हम लिलिना के लिए उपयोग किया जाने वाला कोड है:

<?php
/**
 * Handler for persistent data files
 *
 * @author Ryan McCue <cubegames@gmail.com>
 * @package Lilina
 * @version 1.0
 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
 */

/**
 * Handler for persistent data files
 *
 * @package Lilina
 */
class DataHandler {
    /**
     * Directory to store data.
     *
     * @since 1.0
     *
     * @var string
     */
    protected $directory;

    /**
     * Constructor, duh.
     *
     * @since 1.0
     * @uses $directory Holds the data directory, which the constructor sets.
     *
     * @param string $directory 
     */
    public function __construct($directory = null) {
        if ($directory === null)
            $directory = get_data_dir();

        if (substr($directory, -1) != '/')
            $directory .= '/';

        $this->directory = (string) $directory;
    }

    /**
     * Prepares filename and content for saving
     *
     * @since 1.0
     * @uses $directory
     * @uses put()
     *
     * @param string $filename Filename to save to
     * @param string $content Content to save to cache
     */
    public function save($filename, $content) {
        $file = $this->directory . $filename;

        if(!$this->put($file, $content)) {
            trigger_error(get_class($this) . " error: Couldn't write to $file", E_USER_WARNING);
            return false;
        }

        return true;
    }

    /**
     * Saves data to file
     *
     * @since 1.0
     * @uses $directory
     *
     * @param string $file Filename to save to
     * @param string $data Data to save into $file
     */
    protected function put($file, $data, $mode = false) {
        if(file_exists($file) && file_get_contents($file) === $data) {
            touch($file);
            return true;
        }

        if(!$fp = @fopen($file, 'wb')) {
            return false;
        }

        fwrite($fp, $data);
        fclose($fp);

        $this->chmod($file, $mode);
        return true;

    }

    /**
     * Change the file permissions
     *
     * @since 1.0
     *
     * @param string $file Absolute path to file
     * @param integer $mode Octal mode
     */
    protected function chmod($file, $mode = false){
        if(!$mode)
            $mode = 0644;
        return @chmod($file, $mode);
    }

    /**
     * Returns the content of the cached file if it is still valid
     *
     * @since 1.0
     * @uses $directory
     * @uses check() Check if cache file is still valid
     *
     * @param string $id Unique ID for content type, used to distinguish between different caches
     * @return null|string Content of the cached file if valid, otherwise null
     */
    public function load($filename) {
        return $this->get($this->directory . $filename);
    }

    /**
     * Returns the content of the file
     *
     * @since 1.0
     * @uses $directory
     * @uses check() Check if file is valid
     *
     * @param string $id Filename to load data from
     * @return bool|string Content of the file if valid, otherwise null
     */
    protected function get($filename) {
        if(!$this->check($filename))
            return null;

        return file_get_contents($filename);
    }

    /**
     * Check a file for validity
     *
     * Basically just a fancy alias for file_exists(), made primarily to be
     * overriden.
     *
     * @since 1.0
     * @uses $directory
     *
     * @param string $id Unique ID for content type, used to distinguish between different caches
     * @return bool False if the cache doesn't exist or is invalid, otherwise true
     */
    protected function check($filename){
        return file_exists($filename);
    }

    /**
     * Delete a file
     *
     * @param string $filename Unique ID
     */
    public function delete($filename) {
        return unlink($this->directory . $filename);
    }
}

?>

यह प्रत्येक प्रविष्टि को एक अलग फ़ाइल के रूप में संग्रहीत करता है, जो हमने पाया कि उपयोग के लिए पर्याप्त कुशल है (कोई भी अनावश्यक डेटा लोड नहीं किया गया है और यह सहेजने के लिए तेज़ है)।


8

यदि आप डेटा को बनाए रखने के लिए एक फ्लैट फ़ाइल का उपयोग करने जा रहे हैं, तो डेटा की संरचना करने के लिए XML का उपयोग करें। PHP में एक अंतर्निहित XML पार्सर है


और मानव-पठनीयता के xml नियमों का पालन करें या आप क्रमांकन या json या कुछ और का उपयोग कर सकते हैं।
बेन

बहुत घटिया सलाह। XML का उपयोग कभी नहीं किया जाना चाहिए। यह एक मोटा वशीकरण है।
बजे JG एस्टोट जूल

@JGEstiot देखभाल आगे समझाने के लिए?
अनटुकटाइपएयर

7

यदि आप मानव-पठनीय परिणाम चाहते हैं, तो आप इस प्रकार की फ़ाइल का भी उपयोग कर सकते हैं:

ofaurax|27|male|something|
another|24|unknown||
...

इस तरह, आपके पास केवल एक फ़ाइल है, आप इसे (और मैन्युअल रूप से ठीक) डिबग कर सकते हैं, आप बाद में फ़ील्ड जोड़ सकते हैं (प्रत्येक पंक्ति के अंत में) और PHP कोड सरल है (प्रत्येक पंक्ति के लिए, के अनुसार विभाजित करें)।

हालांकि, कमियां यह है कि आपको कुछ खोजने के लिए पूरी फाइल को पार्स करना चाहिए (यदि आपके पास लाखों प्रविष्टि हैं, तो यह ठीक नहीं है) और आपको डेटा में विभाजक को संभालना चाहिए (उदाहरण के लिए यदि निक वा आरआर है। ordz)।


7

मैंने फ़ाइल में डेटा स्टोर करने के लिए डिज़ाइन किए गए दो सरल कार्य लिखे हैं। यदि आप इस मामले में उपयोगी हैं तो आप अपने लिए न्याय कर सकते हैं। बिंदु एक php वैरिएबल को बचाने के लिए है (यदि यह फ़ाइल के लिए एक स्ट्रिंग या ऑब्जेक्ट है)।

<?php
function varname(&$var) {
    $oldvalue=$var;
    $var='AAAAB3NzaC1yc2EAAAABIwAAAQEAqytmUAQKMOj24lAjqKJC2Gyqhbhb+DmB9eDDb8+QcFI+QOySUpYDn884rgKB6EAtoFyOZVMA6HlNj0VxMKAGE+sLTJ40rLTcieGRCeHJ/TI37e66OrjxgB+7tngKdvoG5EF9hnoGc4eTMpVUDdpAK3ykqR1FIclgk0whV7cEn/6K4697zgwwb5R2yva/zuTX+xKRqcZvyaF3Ur0Q8T+gvrAX8ktmpE18MjnA5JuGuZFZGFzQbvzCVdN52nu8i003GEFmzp0Ny57pWClKkAy3Q5P5AR2BCUwk8V0iEX3iu7J+b9pv4LRZBQkDujaAtSiAaeG2cjfzL9xIgWPf+J05IQ==';
    foreach($GLOBALS as $var_name => $value) {
        if ($value === 'AAAAB3NzaC1yc2EAAAABIwAAAQEAqytmUAQKMOj24lAjqKJC2Gyqhbhb+DmB9eDDb8+QcFI+QOySUpYDn884rgKB6EAtoFyOZVMA6HlNj0VxMKAGE+sLTJ40rLTcieGRCeHJ/TI37e66OrjxgB+7tngKdvoG5EF9hnoGc4eTMpVUDdpAK3ykqR1FIclgk0whV7cEn/6K4697zgwwb5R2yva/zuTX+xKRqcZvyaF3Ur0Q8T+gvrAX8ktmpE18MjnA5JuGuZFZGFzQbvzCVdN52nu8i003GEFmzp0Ny57pWClKkAy3Q5P5AR2BCUwk8V0iEX3iu7J+b9pv4LRZBQkDujaAtSiAaeG2cjfzL9xIgWPf+J05IQ==')
        {
            $var=$oldvalue;
            return $var_name;
        }
    }
    $var=$oldvalue;
    return false;
}

function putphp(&$var, $file=false)
    {
    $varname=varname($var);
    if(!$file)
    {
        $file=$varname.'.php';
    }
    $pathinfo=pathinfo($file);
    if(file_exists($file))
    {
        if(is_dir($file))
        {
            $file=$pathinfo['dirname'].'/'.$pathinfo['basename'].'/'.$varname.'.php';
        }
    }
    file_put_contents($file,'<?php'."\n\$".$varname.'='.var_export($var, true).";\n");
    return true;
}

मैंने पाया कि यह दिलचस्प है और यह बेहतर तरीका है, क्योंकि हम सिर्फ फॉर्मेट किए गए ऐरे को फाइल में डंप करते हैं। हमें इसे फिर से बनाने की जरूरत नहीं है, बस में पढ़ें। इसके अलावा, चर को संपादित करें यह थोड़ा आसान है। मैं कभी भी बड़े डेटा को स्टोर करने के लिए उपयोग नहीं करूंगा, लेकिन मैंने प्रोग्राम के मॉड्यूल को डेटाबेस के बिना स्टोर करना व्यावहारिक पाया। धन्यवाद।
m3nda

7

यह एक व्यावहारिक समाधान के रूप में प्रेरणादायक है:
https://github.com/mhgolkar/FlatFire
यह डेटा को संभालने के लिए कई रणनीतियों का उपयोग करता है ...
[Readme फ़ाइल से कॉपी किया गया]

नि: शुल्क या संरचित या मिश्रित

- STRUCTURED
Regular (table, row, column) format.
[DATABASE]
/   \
TX  TableY
    \_____________________________
    |ROW_0 Colum_0 Colum_1 Colum_2|
    |ROW_1 Colum_0 Colum_1 Colum_2|
    |_____________________________|
- FREE
More creative data storing. You can store data in any structure you want for each (free) element, its similar to storing an array with a unique "Id".
[DATABASE]
/   \
EX  ElementY (ID)
    \________________
    |Field_0 Value_0 |
    |Field_1 Value_1 |
    |Field_2 Value_2 |
    |________________|
recall [ID]: get_free("ElementY") --> array([Field_0]=>Value_0,[Field_1]=>Value_1...
- MIXD (Mixed)
Mixed databases can store both free elements and tables.If you add a table to a free db or a free element to a structured db, flat fire will automatically convert FREE or SRCT to MIXD database.
[DATABASE]
/   \
EX  TY

7

IMHO, आपके पास दो विकल्प हैं यदि आप होमब्रेविंग से बचना चाहते हैं:

  1. SQLite

    यदि आप PDO से परिचित हैं, तो आप एक PDO ड्राइवर स्थापित कर सकते हैं जो SQLite का समर्थन करता है। कभी इसका उपयोग नहीं किया, लेकिन मैंने MySQL के साथ PDO एक टन का उपयोग किया है। मैं इसे एक वर्तमान परियोजना पर एक शॉट देने जा रहा हूं।

  2. एक्सएमएल

    अपेक्षाकृत कम मात्रा में डेटा के लिए यह कई बार किया गया। XMLReader एक लाइटवेट, रीड-फॉरवर्ड, कर्सर-स्टाइल क्लास है। SimpleXML एक XML दस्तावेज़ को एक ऑब्जेक्ट में पढ़ना आसान बनाता है जिसे आप किसी अन्य वर्ग उदाहरण की तरह एक्सेस कर सकते हैं।


5

इस तरह की प्रणाली के साथ एक फ्लैट फ़ाइल डेटाबेस के साथ एक संभावित समस्या की ओर इशारा करते हुए:

data|some text|more data

row 2 data|bla hbalh|more data

...आदि

समस्या यह है कि सेल डेटा में "|" या "\ n" तब डेटा खो जाएगा। कभी-कभी पत्रों के संयोजन द्वारा विभाजित करना आसान होगा जो अधिकांश लोग उपयोग नहीं करेंगे।

उदाहरण के लिए:

स्तंभ फाड़नेवाला: #$% (Shift+345)

पंक्ति फाड़नेवाला: ^&* (Shift+678)

पाठ फ़ाइल: test data#$%blah blah#$%^&*new row#$%new row data 2

फिर उपयोग करें: explode("#$%", $data); use foreach, the explode again to separate columns

या इन पंक्तियों के साथ कुछ भी। इसके अलावा, मैं यह भी जोड़ सकता हूं कि फ्लैट फाइल डेटाबेस कम मात्रा में डेटा (यानी 20 पंक्तियों से कम) वाले सिस्टम के लिए अच्छे हैं, लेकिन बड़े डेटाबेस के लिए विशाल मेमोरी हॉग बन जाते हैं।


अच्छे अंक। इसे एक कदम आगे बढ़ाते हुए, PHP JSON को वास्तव में आसानी से अनुक्रमित कर सकती है। बचना इनपुट बहुत सरल है, इसलिए आपको मज़ेदार स्ट्रिंग संयोजनों का उपयोग करने की आवश्यकता नहीं है, ताकि फ़ाइल अधिक पठनीय हो।
साइपर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.