qBlog Quadina w świecie PHP

7gru/101

Powtarzające się ostatnio pytanie o tablice w tablicach

Na forum.php.pl pojawiło się pytanie, które postanowiłem aż zamieścić na swoim blogu. Pytanie odnosi się do sposobu przechowywania tablic w komórce bazy danych.

Chciałbym przechowywać w jednej kolumnie bazy MySQL pewne dane z PHP, np: $array = array(1, 15, 24, 188) (myślę, że taka tablica może dosięgać nawet 40 rekordów). Mam na względzie dwie wersje:

1. Użycie funkcji explode()
W tym przypadku $array zmieniam na następującą postać: "1,15,24,188". Wrzucam tego stringa do bazy (do jednej komórki).
Pobierając dane, używam funkcji explode(",", $ciag_z_bazy) i w ten sposób pozyskuję potrzebną mi tablicę

2. Użycie serializacji i BLOB'a
W tym przypadku kolumna danych będzie typu BLOB i przy pomocy serialize() zmienną $array wprowadzam do rekordu, a unserialize() pobieram dane z bd.

PYTANIE: który sposób jest najbardziej optymalny?

BLOB to tym w którym możemy przechowywać dane binarne, np. zawartość pliku z obrazkiem. Do wszystkich innych nie ma potrzeby włączać trybu binarnego, bo wszystko po za tym sprowadza się do tekstu. Zserializowana tablica to po prostu string odpowiednio spreparowany, tak aby dało się z niego z powrotem odtworzyć tablicę.

Co do tematu - patrząc od strony technicznej i zasady normalizacji i denormaliazacji tablic, to przechowywanie danych po przecinku w jednej komórce jest karana karą śmierci do lat 3. Niestety w praktyce bardzo często zachodzi potrzeba własnie takiego przechowywania informacji, więc mamy dwie opcje. Albo stworzyć dwie tablice, gdzie druga będzie posiadała klucz obcy do pierwszej i w drugiej kolumnie zawartość. Wtedy można łatwo zrobić GROUP_CONCAT żeby wyświetlić nawet po przecinku JOINowaną drugą tablicę. Albo faktycznie trzebać wszystko w jednej kolumnie po przecinku, albo zserializowane. Polecam jednak po przecinku ze względu na możliwość szykania szybkiego po bazie, bez przelatywania po zbędnych znakach ( {a:12:{ .... }} ). Można wtedy wyszukiwać po prostu LIKE "%...%" i znajdzie na każdej pozycji. Należy jednak pamiętać że LIKE "%...%" różni się od LIKE "...%" tym, ze pierwszy wykonuje się średnio 3,5 raza wolniej od drugiego. To może być dość znaczące przy wyszukiwaniu po tablicy z kilkoma tysiącami/milionami danych.

Podsumowując proponowałbym Ci pierwszą opcję, czyli jedna komórka i explode/implode w przypadku tablicy w której raczej rzadko szukasz i nie ma wiele elementów. Albo opcję z normalizacją (czyli rozdzieleniem na dwie tabele) w przypadku gdy będziesz często szukał i masz dużo elementów. Rozważ te opcje sam - mam nadzieje, że pomogłem.

Zakres tematyczny: Programowanie Dodaj komentarz
Komentarze (1) Trackbacks (0)
  1. Dzięki drogi autorze za te informacje, lubię czytać posty pozbawione dodatkowych uszczypliwości i docinek autorów. Często wpisy na forach trzeba poważnie filtrować – wśród perełek (informacji które się szuka) znajdują się banialuki i inne nie do końca poprawne rozwiązania. Proponowane przez Ciebie, wyłuskane rozwiązanie na pewno się przyda!


Leave a comment

Brak trackbacków.