source

플랫 파일 데이터베이스

factcode 2022. 9. 8. 21:48
반응형

플랫 파일 데이터베이스

PHP에서 플랫 파일 데이터베이스 구조를 만드는 데 대한 모범 사례는 무엇입니까?

SQL과 같은 쿼리 구문을 구현하려고 하는 PHP 플랫 파일 프레임워크가 많이 있습니다.대부분의 경우 제 목적을 상회합니다.(그 시점에서는 데이터베이스만 사용합니다).

코드의 오버헤드를 작게 억제하면서 뛰어난 퍼포먼스와 기능을 얻을 수 있는 우아한 요령이 있을까요?

음, 플랫 데이터베이스의 성질은 무엇입니까?큰지 작은지.어레이가 포함된 단순한 어레이입니까?사용자 프로파일이 그렇게 구축되어 있다면 다음과 같습니다.

$user = array("name" => "bob", 
              "age" => 20,
              "websites" => array("example.com","bob.example.com","bob2.example.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));
}

그러나, 이 실장은, 필요한 애플리케이션이나 데이타베이스의 특성에 의해서 다릅니다.

SQLite를 고려할 수 있습니다.플랫 파일처럼 간단하지만 쿼리를 위한 SQL 엔진을 사용할 수 있습니다.PHP에서도 잘 동작합니다.

제 생각에, "플랫 파일 데이터베이스"를 의미(및 수락한 답변)로 사용하는 것이 반드시 최선의 방법은 아닙니다.우,를 serialize() ★★★★★★★★★★★★★★★★★」unserialize()다른 사용자가 파일을 편집하면 큰 골칫거리가 될 수 있습니다(실제로 사용자가 매번 실행할 "데이터베이스"에 임의의 코드를 넣을 수 있습니다).

개인적으로, 저는 왜 미래를 보지 않는가라고 말하고 싶습니다.독자적인 「독자적인」파일을 작성해, 프로젝트가 폭발적으로 증가해 데이타베이스가 필요하게 되어, 코드의 리팩터링에는 시간과 노력이 너무 많이 소요되기 때문에, 「이것을 데이타베이스에 쓸걸」이라고 생각하고 있습니다.

이로부터, 장래에 원서를 검증해, 규모가 커지면 리팩터링에 며칠을 소비하지 않아도 되는 것을 배웠습니다.이거 어떻게 해?

SQLite. 데이터베이스로 작동하고 SQL을 사용하며 MySQL로 전환하기가 매우 쉽습니다(특히 나처럼 데이터베이스 조작에 추상화된 클래스를 사용하는 경우).

사실, 특히 "Accepted answer" 방식으로는 앱의 메모리 사용량을 대폭 줄일 수 있습니다(모든 "RECORD"를 PHP에 로드할 필요는 없습니다).

제가 고려하고 있는 프레임워크 중 하나는 블로그 플랫폼입니다.원하는 데이터를 날짜별로 정렬할 수 있기 때문에 이 구조에 대해 생각해 보았습니다.

콘텐츠 노드당 1개의 디렉토리:

./content/YYYYMMDDHHMMSS/

다음을 포함한 각 노드의 하위 디렉토리

/tags  
/authors  
/comments  

또한 사전 및 사후 렌더링 콘텐츠 등을 위한 노드 디렉토리에 있는 단순한 텍스트 파일도 있습니다.

이를 통해 단순한 PHP 호출(및 결과 배열의 반전)이 콘텐츠 구조 내의 거의 모든 것에 대해 쿼리할 수 있습니다.

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

"funny"라는 태그가 붙은 모든 기사를 포함한 경로를 반환합니다.

Lilina에 사용하는 코드는 다음과 같습니다.

<?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);
    }
}

?>

각 엔트리를 별도의 파일로 저장하기 때문에 사용할 수 있을 만큼 효율적입니다(불필요한 데이터가 로드되지 않고 저장 속도가 빠릅니다.

IMHO야, 너 두 개...집에서 만드는 것을 피하고 싶다면 세 가지 옵션이 있습니다.

  1. SQLite

PDO에 익숙한 경우 SQLite를 지원하는 PDO 드라이버를 설치할 수 있습니다.사용한 적은 없지만 MySQL에서 PDO를 많이 사용한 적이 있습니다.현재 진행 중인 프로젝트에 한 번 도전해 보겠습니다.

  1. XML

비교적 적은 양의 데이터로 여러 번 이 작업을 수행했습니다.XMLReader는 가벼운 읽기-전송 커서 스타일의 클래스입니다.SimpleXML을 사용하면 XML 문서를 다른 클래스 인스턴스와 마찬가지로 액세스할 수 있는 개체로 쉽게 읽을 수 있습니다.

  1. JSON(갱신)

읽기/쓰기 파일과 json_decode/json_encode만 있으면 적은 양의 데이터에 적합합니다.PHP가 JSON 트리를 메모리에 로드하지 않고 탐색할 수 있는 구조를 제공하는지는 확실하지 않습니다.

플랫 파일을 사용하여 데이터를 유지하려면 XML을 사용하여 데이터를 구성합니다.PHP에는 XML 파서가 내장되어 있습니다.

사람이 읽을 수 있는 결과를 원하는 경우 다음 유형의 파일도 사용할 수 있습니다.

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

이렇게 하면 파일이 1개뿐이므로 쉽게 디버깅할 수 있고(및 수동으로 수정할 수 있습니다), 나중에 필드를 추가할 수 있으며(각 행 끝에), PHP 코드는 간단합니다(각 행에 대해 |에 따라 분할됩니다).

단, 단점은 파일 전체를 해석하여 검색(수백만 개의 엔트리를 가지고 있는 경우는 문제가 없음)하고 데이터 구분자(예를 들어 닉이 WaR|ordz인 경우)를 처리해야 한다는 것입니다.

데이터를 파일에 저장하기 위해 설계된 두 가지 간단한 기능을 작성했습니다.이 경우에 도움이 되는지 여부는 당신이 판단할 수 있습니다.포인트는 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;
}

이것은 실용적인 해결책으로서 고무적입니다.
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

다음과 같은 유형의 시스템에서 플랫 파일 데이터베이스에 발생할 수 있는 문제를 지적합니다.

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줄 미만)이지만 대규모 데이터베이스에서는 대용량 메모리 호그가 됩니다.

언급URL : https://stackoverflow.com/questions/85/flat-file-databases

반응형