배수 동의를 허용하는 PHP 용 문서 저장소. 새로운 서비스를 설치하는 오버 헤드없이 MongoDB 또는 CouchDB에 대한 미니멀리스트 대안입니다.
또한 작은 풋 프린트 데이터베이스로 작동합니다.
평균적으로 SMB는 한 달에 100 개의 송장을 생성합니다. 따라서 SMB가 10 년당 12000 개의 송장을 생성한다고 가정 해 봅시다.
고객, 세부 사항 (세부 사항 당 약 1-5 줄)으로 12000 송장 생성 및 i7/ssd/16GB/Windows 64Bits에서 12000 송장을 생성합니다.

100 동시 테스트 (쓰기 및 읽기)가있는 테스트, 10 회 테스트.
| n ° | 읽습니다 | (MS) | 읽습니다 | 오류 |
|---|---|---|---|---|
| 1 | 100 | 7471 | 100 | 0 |
| 2 | 100 | 7751 | 100 | 0 |
| 3 | 100 | 7490 | 100 | 0 |
| 4 | 100 | 7480 | 100 | 0 |
| 5 | 100 | 8199 | 100 | 0 |
| 6 | 100 | 7451 | 100 | 0 |
| 7 | 100 | 7476 | 100 | 0 |
| 8 | 100 | 7244 | 100 | 0 |
| 9 | 100 | 7573 | 100 | 0 |
| 10 | 100 | 7818 | 100 | 0 |
include " lib/DocumentStoreOne.php " ;
use eftec DocumentStoreOne DocumentStoreOne ;
try {
$ flatcon = new DocumentStoreOne ( " base " , ' tmp ' );
// or you could use:
// $flatcon = new DocumentStoreOne(__DIR__ . "/base", 'tmp');
} catch ( Exception $ e ) {
die ( " Unable to create document store. Please, check the folder " );
}
$ flatcon -> insertOrUpdate ( " somekey1 " , json_encode ( array ( " a1 " => ' hello ' , " a2 " => ' world ' ))); // or you could use serialize/igbinary_serialize
$ doc = $ flatcon -> get ( " somekey1 " );
$ listKeys = $ flatcon -> select ();
$ flatcon -> delete ( " somekey1 " ); include " lib/DocumentStoreOne.php " ;
use eftec DocumentStoreOne DocumentStoreOne ;
$ doc = new DocumentStoreOne ( " base " , " task " , ' folder ' );
//also: $doc=new DocumentStoreOne(__DIR__."/base","task",'folder');
$ doc -> serializeStrategy = ' php ' ; // it sets the strategy of serialization to php
$ doc -> autoSerialize ( true ); // autoserialize
$ flatcon -> insertOrUpdate ( " somekey1 " , array ( " a1 " => ' hello ' , " a2 " => ' world ' )); DocumentStoreOne 인스턴스를 만듭니다.
| 전략 | 유형 | 섬기는 사람 | 기준 |
|---|---|---|---|
| dso_auto | 사용 가능한 최고의 전략 (기본값)을 설정합니다. | 의존합니다 | - |
| dso_folder | 문서를 잠금/잠금 해제하기 위해 폴더를 사용합니다 | - | 0.3247 |
| DSO_APCU | 문서 잠금/잠금 해제에 APCU를 사용합니다 | - | 0.1480 |
| dso_redis | 문서 잠금/잠금 해제에 Redis를 사용합니다 | 로컬 호스트 : 6379 | 2.5403 (최악) |
| dso_none | 문서를 잠그거나 잠금 해제하는 데 아무것도 사용하지 않습니다. 가장 빠른 방법이지만 배수 사용자에게는 안전하지 않습니다. | 0 |
| 전략 | 유형 |
|---|---|
| PHP | serialize () 함수를 사용하여 직렬화합니다 |
| php_array | include ()/var_export () 함수를 사용하여 직렬화합니다. 결과는 PHP 코드 파일이기 때문에 결과는 OpCache에 캐시 될 수 있습니다. |
| json_object | JSON (Object)을 사용하여 직렬화됩니다. |
| JSON_ARRAY | JSON을 사용하여 직렬화됩니다 (배열) |
| CSV | CSV 파일을 사용하여 직렬화됩니다. |
| igbinary | IGBinary 파일을 사용하여 직렬화됩니다. |
| 없음 (기본값) | 직렬화되지 않습니다. 정보는 수동으로 직렬화/비 시리얼 화되어야합니다 |
예 :
$ flatcon = new DocumentStoreOne ( __DIR__ . " /base " ); // new instance, using the folder /base, without serialization and with the default data
$ flatcon = new DocumentStoreOne ( __DIR__ . " /base " , '' , ' auto ' , '' , ' php_array ' ); // new instance and serializing using php_array벤치 마크 시간 (초) 100 삽입물을 추가하는 데 시간이 걸립니다.
use eftec DocumentStoreOne DocumentStoreOne ;
include " lib/DocumentStoreOne.php " ;
try {
$ flatcon = new DocumentStoreOne ( __DIR__ . " /base " , ' tmp ' );
} catch ( Exception $ e ) {
die ( " Unable to create document store. " . $ e -> getMessage ());
} use eftec DocumentStoreOne DocumentStoreOne ;
include " lib/DocumentStoreOne.php " ;
try {
$ flatcon = new DocumentStoreOne ( " /base " , ' tmp ' ,DocumentStoreOne:: DSO_APCU );
} catch ( Exception $ e ) {
die ( " Unable to create document store. " . $ e -> getMessage ());
}Collection이 유효한 경우 (하위 폴더) TRUE를 반환합니다.
$ ok = $ flatcon -> isCollection ( ' tmp ' );현재 컬렉션을 설정합니다
$ flatcon -> collection ( ' newcollection ' ); // it sets a collection.이 명령은 중첩 될 수 있습니다.
$ flatcon -> collection ( ' newcollection ' )-> select (); // it sets and return a query컬렉션이 정확하거나 존재하는지 확인하지 않습니다. 옳은지 확인하려면 iscollection ()을 사용해야합니다.
정보를 자동 직렬화하려면 설정하고 직렬화 방법을 설정합니다. 생성자를 사용하여 설정할 수도 있습니다.
| 전략 | 유형 |
|---|---|
| PHP | serialize () 함수를 사용하여 직렬화합니다. |
| php_array | include ()/var_export () 함수를 사용하여 직렬화합니다. 결과는 PHP 파일이기 때문에 결과는 OpCache에 캐시 될 수 있습니다. |
| json_object | JSON (Object)을 사용하여 직렬화됩니다. |
| JSON_ARRAY | JSON을 사용하여 직렬화됩니다 (배열) |
| CSV | CSV 파일을 사용하여 직렬화됩니다. |
| igbinary | IGBinary 파일을 사용하여 직렬화됩니다. |
| 없음 (기본값) | 직렬화되지 않습니다. 정보는 수동으로 직렬화/비 시리얼 화되어야합니다 |
컬렉션 (기본 폴더 내부에 새 폴더)을 만듭니다. 작업이 실패하면 False를 반환합니다. 그렇지 않으면 진실을 반환합니다
$ flatcon -> createCollection ( ' newcollection ' );
$ flatcon -> createCollection ( ' /folder1/folder2 ' ); 표시된 $ id 에 새 문서 (문자열)를 삽입합니다. 문서가 존재하면 업데이트됩니다.
$ 시도는 시도 수를 나타냅니다. 기본값은 -1 (기본 시도 수)입니다.
// if we are not using auto serialization
$ doc = json_encode ([ " a1 " => ' hello ' , " a2 " => ' world ' ]);
$ flatcon -> insertOrUpdate ( " 1 " , $ doc ); // it will create a document called 1.dson in the base folder.
// if we are using auto serialization
$ flatcon -> insertOrUpdate ( " 1 " ,[ " a1 " => ' hello ' , " a2 " => ' world ' ]);문서가 잠겨 있으면 사용할 수있을 때까지 또는 "NTH"수의 시도 후에 다시 시작합니다 (기본적으로 100 초에 10 초에 해당하는 100 개의 시도).
삽입 또는 업데이트보다 빠릅니다.
표시된 $ id 에 새 문서 (문자열)를 삽입합니다. 문서가 존재하면 False를 반환합니다.
$ 시도는 시도 수를 나타냅니다. 기본값은 -1 (기본 시도 수)입니다.
// if we are not using auto serialization
$ doc = json_encode ( array ( " a1 " => ' hello ' , " a2 " => ' world ' ));
$ flatcon -> insert ( " 1 " , $ doc );
// if we are using auto serialization
$ flatcon -> insert ( " 1 " ,[ " a1 " => ' hello ' , " a2 " => ' world ' ]);문서가 잠겨 있으면 사용할 수있을 때까지 또는 "NTH"수의 시도 후에 다시 시작합니다 (기본적으로 100 초에 10 초에 해당하는 100 개의 시도).
표시된 $ id 에서 문서 (문자열)를 업데이트하십시오. 문서가 존재하지 않으면 False를 반환합니다
$ 시도는 시도 수를 나타냅니다. 기본값은 -1 (기본 시도 수)입니다.
// if we are not using auto serialization
$ doc = json_encode ([ " a1 " => ' hello ' , " a2 " => ' world ' ]);
$ flatcon -> update ( " 1 " , $ doc );
// if we are using auto serialization
$ flatcon -> update ( " 1 " ,[ " a1 " => ' hello ' , " a2 " => ' world ' ]);문서가 잠겨 있으면 사용할 수있을 때까지 또는 "NTH"수의 시도 후에 다시 시작합니다 (기본적으로 100 초의 시도는 10 초에 해당합니다).
문서 $ id 를 읽습니다. 문서가 존재하지 않거나 읽을 수 없으면 False를 반환합니다.
$ 시도는 시도 수를 나타냅니다. 기본값은 -1 (기본 시도 수)입니다.
$ doc = $ flatcon -> get ( " 1 " ); // the default value is false
$ doc = $ flatcon -> get ( " 1 " ,- 1 , ' empty ' );문서가 잠겨 있으면 사용할 수있을 때까지 또는 "NTH"수의 시도 후에 다시 시작합니다 (기본적으로 100 초에 10 초에 해당하는 100 개의 시도).
문서 $ id 필터링 된 문서를 읽습니다. 문서가 존재하지 않거나 읽을 수 없으면 False를 반환합니다.
$ 시도는 시도 수를 나타냅니다. 기본값은 -1 (기본 시도 수)입니다.
// data in rows [['id'=>1,'cat'=>'vip'],['id'=>2,'cat'=>'vip'],['id'=>3,'cat'=>'normal']];
$ data = $ this -> getFiltered ( ' rows ' ,- 1 , false ,[ ' cat ' => ' normal ' ]); // [['id'=>3,'cat'=>'normal']]
$ data = $ this -> getFiltered ( ' rows ' ,- 1 , false ,[ ' type ' => ' busy ' ], false ); // [2=>['id'=>3,'cat'=>'normal']]문서가 잠겨 있으면 사용할 수있을 때까지 또는 "NTH"수의 시도 후에 다시 시작합니다 (기본적으로 100 초에 10 초에 해당하는 100 개의 시도).
이름 $ 이름 의 문서에 값을 추가합니다. 새 값이 추가되므로 전체 문서를 작성하지 않습니다. 예를 들어 로그 파일에 유용합니다.
a) 값이 존재하지 않으면 $ addValue로 생성됩니다. 그렇지 않으면 참으로 돌아갑니다
b) 값이 존재하면 $ addValue가 추가되고 True가 반환됩니다.
c) 그렇지 않으면 거짓을 반환합니다
$ seq = $ flatcon -> appendValue ( " log " , date ( ' c ' ). " new log " );새로운 시퀀스를 읽거나 생성합니다.
a) 시퀀스가 존재하면 $ 간격 으로 증가 하고이 값이 반환됩니다.
b) 시퀀스가 존재하지 않으면 $ init 로 생성 되고이 값이 반환됩니다. c) 라이브러리가 시퀀스를 만들 수 없거나 잠금 할 수 없거나 시퀀스가 존재하지만 읽을 수 없으면 거짓을 반환합니다.
$ seq = $ flatcon -> getNextSequence ();$ id = get ( 'genseq_')가있는 시퀀스를 들여다 볼 수 있지만 권장되지 않습니다.
시퀀스가 손상되면 $ init로 재설정됩니다.
시퀀스 목록을 예약 해야하는 경우 $ REDEBDEDDITIONAL을 사용할 수 있습니다.
$ seq = $ flatcon -> getNextSequence ( " seq " ,- 1 , 1 , 1 , 100 ); // if $seq=1, then it's reserved up to the 101. The next value will be 102.시간, 임의의 값 및 ServerID에 따라 고유 한 시퀀스 (64 비트 정수)를 반환합니다.
충돌 가능성 (동일한 값의 생성)은 1/4095 (0.0001 초마다 실행 된 두 가지 작업 당)입니다.
$ this -> nodeId = 1 ; // if it is not set then it uses a random value each time.
$ unique = $ flatcon -> getSequencePHP (); 문서 $ id가 존재하는지 확인합니다. 문서가 존재하면 참으로 반환됩니다. 그렇지 않으면 false를 반환합니다.
$ 시도는 시도 수를 나타냅니다. 기본값은 -1 (기본 시도 수)입니다.
유효성 검사는 문서가 완전히 잠금 해제 된 경우에만 발생합니다.
$ found = $ flatcon -> ifExist ( " 1 " );문서가 잠겨 있으면 사용할 수있을 때까지 또는 "NTH"수의 시도 후에 다시 시작합니다 (기본적으로 100 초의 시도는 10 초에 해당합니다).
문서 $ id를 삭제합니다. 문서가 존재하지 않거나 삭제할 수없는 경우 false를 반환합니다.
$ 시도는 시도 수를 나타냅니다. 기본값은 -1 (기본 시도 수)입니다.
$ doc = $ flatcon -> delete ( " 1 " );문서가 잠겨 있으면 사용할 수있을 때까지 또는 "NTH"수의 시도 후에 다시 시작합니다 (기본적으로 100 초의 시도는 10 초에 해당합니다).
컬렉션에 저장된 모든 ID를 반환합니다.
$ listKeys = $ flatcon -> select ();
$ listKeys = $ flatcon -> select ( " invoice_* " );잠긴 문서가 포함되어 있습니다.
$ iddestination 에 문서 $ idorigin을 복사하십시오
$ bool = $ flatcon -> copy ( 20 , 30 );문서 대상이 있으면 교체되었습니다
$ idorigin 의 문서 이름을 $ iddestination 으로 바꿉니다
$ bool = $ flatcon -> rename ( 20 , 30 );문서 대상이 존재하면 작동이 실패합니다.
STDClass를 특정 클래스로 변환합니다.
$ inv = new Invoice ();
$ invTmp = $ doc -> get ( ' someid ' ); //$invTmp is a stdClass();
DocumentStoreOne:: fixCast ( $ inv , $ invTmp ); 객체 배열 인 멤버와 함께 작동하지 않습니다. 배열은 stdclass로 유지됩니다.
다음 분야는 공개되어 있으며 런타임 중에 변경 될 수 있습니다.
| 필드 | 유형 |
|---|---|
| $ 데이터베이스 | 데이터베이스의 문자열 루트 폴더 |
| $ 컬렉션 | 데이터베이스의 String Current Collection (subfolder) |
| $ maxlocktime = 120 | 잠금의 int maximium 지속 시간 (초). 기본적으로 2 분입니다 |
| $ defaultNumretry = 100 | int 기본 검색 수. 기본적으로 100x0.1sec = 10 초를 시도합니다 |
| $ intervalbetween -retry = 100000 | 회수 간 INT 간격 (마이크로 초). 100000은 0.1 초를 의미합니다 |
| $ docext = ". dson" | 문자열 기본 확장 (DOT 포함) |
| $ keyencryption = "" | 문자열은 키가 저장 될 때 (파일 이름) 암호화되어 있는지 여부를 나타냅니다. 빈 수단, 암호화가 없습니다. MD5, SHA1, SHA256, .. |
예:
$ ds = new DocumentStoreOne ();
$ ds -> maxLockTime = 300 ; $ ds = new DocumentStoreOne ();
$ ds -> insert ( ' 1 ' , ' hello ' ); // it stores the document 1.dson
$ ds -> keyEncryption = ' SHA256 ' ;
$ ds -> insert ( ' 1 ' , ' hello ' ); // it stores the document 6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b.dson 수동으로 수행 할 수 있습니다. 이 시스템은 모든 값을 읽는 대신 쉽게 액세스 할 수있는 사전 계산 된 값을 저장할 수 있습니다.
다음 연습이라고 가정 해 봅시다. 구매 목록이 있습니다.
| ID | 고객 | 나이 | 섹스 | 제품 구매 | 양 |
|---|---|---|---|---|---|
| 14 | 남자 | 33 | 중 | 33 | 3 |
| 25 | 안나 | 22 | 에프 | 32 | 1 |
| ProductCode | 단위 가격 |
|---|---|
| 32 | 23.3 |
| 33 | 30 |
John은 코드 33으로 3 개의 제품을 구입했습니다. 제품 33은 단위당 $ 23.3입니다.
질문, 모든 고객이 얼마를 지불 했습니까?.
간단한 연습이며 관계형 데이터베이스에 더 적합합니다 (구매 내부로 결합 제품을 선택하십시오). 그러나 문서가 데이터베이스에 저장하기에 길거나 복잡한 경우 문서 저장소가 빛나는 곳이 있습니다.
// 1) open the store
$ ds = new DocumentStoreOne ( ' base ' , ' purchases ' ); // we open the document store and selected the collection purchase.
$ ds -> autoSerialize ( true , ' auto ' );
// 2) reading all products
// if the list of products holds in memory then, we could store the whole list in a single document (listproducts key)
$ products = $ ds -> collection ( ' products ' )-> get ( ' listproducts ' );
// 3) we read the keys of every purchases. It could be slow and it should be a limited set (<100k rows)
$ purchases = $ ds -> collection ( ' purchases ' )-> select (); // they are keys such as 14,15...
$ customerXPurchase =[];
// 4) We read every purchase. It is also slow. Then we merge the result and obtained the final result
foreach ( $ purchases as $ k ) {
$ purchase = $ ds -> get ( $ k );
@ $ customerXPurchase [ $ purchase -> customer ]+=( $ purchase -> amount * @ $ products [ $ purchase -> productpurchase ]); // we add the amount
}
// 5) Finally, we store the result.
$ ds -> collection ( ' total ' )-> insertOrUpdate ( $ customerXPurchase , ' customerXPurchase ' ); // we store the result.| 고객 | 값 |
|---|---|
| 남자 | 69.9 |
| 안나 | 30 |
코드에서 수행되므로 하이브리드 시스템을 만들 수 있습니다 (Relational Database+Store+Memory Cache).
다음 정보를 직렬화하고 싶다고 가정 해 봅시다.
$ input =[[ ' a1 ' => 1 , ' a2 ' => ' a ' ],[ ' a1 ' => 2 , ' a2 ' => ' b ' ]];값은 직렬화되지 않으므로 객체, 어레이 또는 기타 구조를 직렬화 할 수 없습니다. 문자열과 만 작동합니다.
값이 저장되는 방법
helloworld
값이 반환되는 방법
" helloworld " PHP의 직렬화는 직렬화 및 비 시리얼 화하는 가장 빠른 방법 중 하나이며, 동일한 구조 (클래스, 배열, 필드)로 동일한 값을 항상 반환합니다.
그러나 저장된 값은 길 수 있습니다.
값이 저장되는 방법 :
a:2:{i:0;a:2:{s:2:"a1";i:1;s:2:"a2";s:1:"a";}i:1;a:2:{s:2:"a1";i:2;s:2:"a2";s:1:"b";}}
값이 반환되는 방법 :
[['a1'=>1,'a2'=>'a'],['a1'=>2,'a2'=>'b']]
이 직렬화는 PHP 코드를 생성합니다. 이 코드는 장점이지만 몇 가지 좋은 기능이 있습니다.
값이 저장되는 방법 :
<?php /** @generated */
return array (
0 =>
array (
' a1 ' => 1 ,
' a2 ' => ' a ' ,
),
1 =>
array (
' a1 ' => 2 ,
' a2 ' => ' b ' ,
),
);값이 반환되는 방법 :
[['a1'=>1,'a2'=>'a'],['a1'=>2,'a2'=>'b']]
두 방법 모두 직렬화 및 탈사를 위해 JSON과 함께 작동하지만 첫 번째 반품은 항상 연관 배열이고 다른 방법은 객체 (stdClass)를 반환 할 수 있습니다.
찬성:
단점 :
값이 저장되는 방법 :
[{"a1":1,"a2":"a"},{"a1":2,"a2":"b"}]
값이 반환되는 방법 :
[[ ' a1 ' => 1 , ' a2 ' => ' a ' ],[ ' a1 ' => 2 , ' a2 ' => ' b ' ]] // array
[stdClass{ ' a1 ' => 1 ,'a2'=>'a'},stdClass{ ' a1 ' => 2 ,'a2'=>'b'}] // object기본적 으로이 라이브러리는 오류 또는 예외가 발생하면 오류가 발생합니다. 일부 방법은 던지기 오류를 피할 수 있지만 대부분 오류가 발생할 수 있습니다.
오류는 시도/캐치 캐치 아블입니다.
// throw an error:
$ this -> throwable = true ; // (default value is true) If false, then the errors are stored in $this->latestError
try {
$ this -> insert ( ' id1 ' , ' values ' );
} catch ( $ ex ) {
var_dump ( $ ex );
} // not throw an error:
$ this -> throwable = false ;
$ this -> insert ( ' id1 ' , ' values ' );
if ( $ this -> latestError ) {
var_dump ( $ this -> latestError );
}
$ this -> resetError ();또는 예외를 던지지 않도록 사용할 수도 있습니다.
// not throw an error:
$ this ->-> noThrowOnError ()-> insert ( ' id1 ' , ' values ' );
// but you can still see the latest error:
if ( $ this -> latestError ) {
var_dump ( $ this -> latestError );
}다음과 같이 CSV로 작업 할 수 있습니다.
$ doc = new DocumentStoreOne ( __DIR__ . " /base " , '' , ' none ' , '' , ' csv ' ); // set your strategy to csv.
$ doc -> docExt = ' .csv ' ; // (optional), you can set the extension of the document
$ doc -> csvPrefixColumn = ' col_ ' ; // (optional), you can set the name of the columns (if the csv doesn't have columns)
$ doc -> csvStyle (); // (optional) not needing, but you can use to set your own specifications of csv, for example tab-separated, etc.
$ doc -> regionalStyle (); // (optional) not needing, but you can use to set your own regional settings.
$ values =[
[ ' name ' => ' john1 ' , ' age ' => 22 ],
[ ' name ' => ' john2 ' , ' age ' => 22 ],
[ ' name ' => ' john3 ' , ' age ' => 22 ],
];
$ doc -> delete ( ' csv1 ' );
$ doc -> insert ( ' csv1 ' , $ values );[runtimeexception] repo.packagist.org에 패키지 eftec/docum : 잘못된 버전 문자열 "^5.6".