Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL] Dane zerojedynkowe
Forum PHP.pl > Forum > Przedszkole
SmokAnalog
Witajcie,

w jaki sposób najlepiej przechowywać dane zerojedynkowe w bazie? Potrzebna mi baza czarno-białych obrazków zapisanych w ten sposób. Czy jest jakiś wbudowany sposób konwersji w MySQL? Przypuszczam, że pewnie najlepiej będzie zamienić to na postać 256-bitową i zapisać w polu binarnie. Czy mam rację? I jak to potem z powrotem odczytać?
werdan
Może BLOB (binary large object), TEXT ("01011001"), TEXT ("2FE4FF") - hex.

Nie wiem jak masz te bity pogrupowane.
SmokAnalog
Cytat(werdan @ 25.11.2013, 22:25:55 ) *
Nie wiem jak masz te bity pogrupowane.

Nie rozumiem jakie to ma znaczenie. Muszę po prostu "skompresować" te dane. Zapisywanie tego jako TEXT w postaci 0010101010 byłoby wyjątkowym marnotrawstwem miejsca w bazie. Szesnastkowo już lepiej, ale to dalej nie jest optymalny zapis.

Widzę, że jest w MySQL funkcja compress, ale czy to najlepszy sposób na kompresję tych danych? Zrobiłem test i ta metoda daje mi zmniejszenie rozmiaru pola o średnio 47% z dużym odchyleniem standardowym. Rozumiem, że teoretycznie dane zapisane w postaci zer i jedynek można zmniejszyć 8-krotnie, bo w polu typu TEXT każdy znak to jeden bajt, a każdy bajt to 8 bitów. Czy dobrze rozumiem?
werdan
>Nie rozumiem jakie to ma znaczenie.

Chodziło mi o układ tego binarnego zapisu. Czy obrazki mają stałą szerokosc, etc?

>Zapisywanie tego jako TEXT w postaci 0010101010 byłoby wyjątkowym marnotrawstwem miejsca w bazie. Szesnastkowo już lepiej, ale to dalej nie jest optymalny zapis.

Szesnastkowo 8 znaków binarnych zamieniasz na 2. (11111111 = FF)

> Rozumiem, że teoretycznie dane zapisane w postaci zer i jedynek można zmniejszyć 8-krotnie, bo w polu typu TEXT każdy znak to jeden bajt, a każdy bajt to 8 bitów.
Nie kazda liczbe z tego zakresu da sie zapisac w TEXT jako text. Musiałbyś uzyc base64, ale ten z 2 znaków robi 3.

Mysle, ze najlepszym rozwiazaniem byłby BLOB, gdzie 1 znak to 8 bitów.

Podsumowujac:
HEX: 16 bitów = 4 znaki
TXT: 16 bitów = 3 znaki
BLOB: 16 bitów = 2 znaki

Mozesz jeszcze gzies po drodze zrobić jakąs kompresie tego (gz).
SmokAnalog
No i teraz jak zapisać to do BLOB-a?
nospor
A takie pytanie z czystej ciekawosci: a po co tak w ogole kombinujesz?
SmokAnalog
To są obrazki, z których będę musiał wyciągać informacje o pikselach, tzn. czy na danych współrzędnych jest piksel czy go nie ma. Mógłbym zapisywać to np. jako PNG i pobierać piksele stamtąd, ale to będzie zbyt ciężkie. Obrazków będzie w bazie bardzo dużo, niektóre sporych rozmiarów, więc chciałbym ładnie upakować ten zapis.
nospor
A czemu obrazkow nie zapisujesz na dysku a w bazie tylko info o nich?
SmokAnalog
Bo to są obrazki logiczne, tzw. nonogramy smile.gif Nigdzie nie będą wyświetlane jako zwykły obrazek, a po drugie nawet gdyby tak było, to odtwarzanie ich struktur z pliku PNG za bardzo obciążałoby serwer.
nospor
Ok, ciekawosc zaspokojona smile.gif
werdan
  1.  
  2. function hex2asc($myin) {
  3. $myout = "";
  4. for ($i=0; $i<strlen($myin)/2; $i++) {
  5. $myout.=chr(base_convert(substr($myin,$i*2,2),16,10));
  6. }
  7. return $myout;
  8. }
  9.  
  10. $b = "0101001101110100011000010110001101101011";
  11.  
  12.  
  13. echo pack('H*', base_convert($b, 2, 16)); //1
  14. echo PHP_EOL;
  15. echo PHP_EOL;
  16. echo hex2asc(dechex(bindec($b))); //2
  17.  


Tu są 2 sposoby, musisz potestowac ze swoimi danymi.
1 i 2 dają to samo, ale róznymi metodami.
SmokAnalog
Dzięki, ale dlaczego mam się ograniczać do zapisu16-tkowego?
werdan
>dlaczego mam się ograniczać do zapisu16-tkowego?

Nie rozumiem biggrin.gif
Musisz zapisac bajty w BLOB. Max wartosc w bajcie to 255 (FF), czyli 16 * 16^1 + 16 * 16^0. Musza byc szesnastki


  1.  
  2. $b = "1010011011101000110000101100011011010110";
  3.  
  4. $file = 'bintest';
  5. file_put_contents($file, pack('H*', base_convert($b, 2, 16)));
  6.  
  7. $res = file_get_contents($file);
  8. $r = unpack('H*', $res);
  9.  
  10. echo $b.PHP_EOL;
  11. echo base_convert($r[1], 16, 2);



To przykład z zapisem do pliku i odczytem.

Tu jest jeszcze jedne bład.
Jak jest zero na poczatku ciagu binarnego, to po odczycie i konwersji do bin, nie ma zera. Musze cos pomyslec, ale teraz wracam do roboty, bo mnie gonią biggrin.gif
Pomysle cos po południu.
SmokAnalog
Cytat(werdan @ 26.11.2013, 11:11:28 ) *
Musisz zapisac bajty w BLOB. Max wartosc w bajcie to 255 (FF), czyli 16 * 16^1 + 16 * 16^0. Musza byc szesnastki

Nie wiem czy dobrze Cię rozumiem. Ciąg znaków zapisany w postaci ciągu binarnego (nie mylić z postacią binarną) prezentuje jeden bit informacji na jeden bajt zapisu. Postać szesnastkowa prezentuje cztery bity informacji na jeden bajt, ale to wciąż nie jest optimum, bo chcemy zapisać bajt informacji na bajt. Stąd moje pytanie co rozumiesz przez "musi być szesnastkowo". System szesnastkowy to nie jest system zapisu o najwyższym stopniu skondensowania na świecie. Możesz zapisywać liczby 17-tkowo, 500-kowo, trylionowo - jak sobie wymarzysz.

Jeden znak w polach tekstowych to jeden bajt, czyli 8 bitów. W idealnym przypadku zapis na przykład "01010101" (8 bitów) zostałby zapisany w postaci JEDNEGO znaku w bazie danych, czyli szukamy systemu o podstawie 256.
werdan
Troche nie kumam biggrin.gif


W pliku/bazie zapisujesz bajty. 1 bajt to 8 bitów, czyli za pomocą 1 bajta możesz zapisac wartosci 0-255, czyli (0h - FFh).

>W idealnym przypadku zapis na przykład "01010101" (8 bitów) zostałby zapisany w postaci JEDNEGO znaku w bazie danych, czyli szukamy systemu o podstawie 256.
To własnie robi moj przykład powyzej.

Zamienia 8 bitów na 1 znak hex z zakresu 0 - 255.
SmokAnalog
Cytat(werdan @ 1.12.2013, 13:57:22 ) *
To własnie robi moj przykład powyzej.

Zamienia 8 bitów na 1 znak hex z zakresu 0 - 255.

Nie ma czegoś takiego jak 1 znak hex z zakresu 0 - 255, tak samo jak nie ma cyfry (w rozumieniu naszego systemu dziesiętnego) 10, 11, 12 itd. 1 znak heksadecymalny przechowuje wartości z zakresu 0 - 15, a zakres 0 - 255 wymaga użycia dwóch znaków.
werdan
Ten znak to bład myslowy. Chodziło mi o bajt.

Tak wyglada plik z przykładu w hexedytorze.
http://s16.postimg.org/51tgdcsth/bintest.jpg

To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.