Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP + MySQL] Przechowywanie danych jako tablic a optymalność
Forum PHP.pl > Forum > PHP
Jazi
Witam wszystkich,
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?

Dzięki z góry za podpowiedzi i udzieloną pomoc.
Pozdrawiam.
CuteOne
Mi osobiście BLOB bardziej kojarzy się z przechowywaniem plików niż danych np. konfiguracyjnych winksmiley.gif Dlatego obstawał bym za explode() - czy jest wydajniejsze, możliwe, że nie ale daje możliwość operacji na stringu przed jego eksportem do tablicy. Czy teraz ci się to przyda hmmm pewnie nie ale w przyszłości, możesz np. chcieć pozbyć się wszystkich 10 lub 15 zanim załadujesz tablicę danymi smile.gif
krowal
Jeśli będziesz te dane tylko przechowywał to raczej nie będzie miało znaczącego wpływu na optymalność. Co innego gdy będziesz chciał wykorzystać to pole w WHERE, wtedy będzie tak jak przy korzystaniu z pola tekstowego smile.gif Swoją drogą, czasami korzystam z przechowywania dodatkowych danych dot. rekordu w taki właśnie sposób, są to jednak takie dane, których nie używam przy budowaniu kryteriów wybierania rekordów. Jak by nie było, nie mają one u mnie wpływu na szybkość wykonania zapytania.
Jazi
A czy BLOB może być wykorzystywany w taki sposób, jak piszesz, poprzez WHERE?
Quadina
BLOB niestety jest niesamowicie wolny jeżeli chodzi o cokolwiek w WHERE - to raczej taka skrzynka do danych kojarzona po innych parametrach tego rekordu.
Jazi
Zatem odradzacie używania BLOBa? Jak zrobię wersję z explode, to mógłbym szukać jakoś po LIKE.
tr@k
A po co Ci BLOB do serializowanej tablicy, przecież to też string.
Jazi
Myślałem, że każdy typ danych, jaki wsadzamy do BLOBa, trzeba zserializować. Nie jest tak?
Quadina
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.
Jazi
Konkretna i pomocna odpowiedź. Dziękuje smile.gif.
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.