[MySQL] Dwuwymiarowa nieskończona baza danych?
Moderator: Pomocy?!
[MySQL] Dwuwymiarowa nieskończona baza danych?
Przeglądarka: Mozilla/5.0 (Windows; U; Windows NT 5.1; pl; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4
Mam mały (chyba) problem związany z bazami danych MySQL. Ponieważ chodzi ogólnie o ideę (zasadę działania, konstrukcję bazy danych), więc moż będzie w stanie mi pomóc ktoś, kto nawet nie ma doświadczenia z samym MySQLem. Moja wiedza na ten temat jest w 100% na bazie samouctwa i nie umiem sobie z tym (zdaje się prostym) problemem poradzić. Możliwe, że problem jest trywialny, tylko ja tego nie widzę.
a) Problem: Jak stworzyć (zaimplementować) dwuwymiarową bazę danych (tabelę) o nieskończonej (teoretycznie) liczbie kolumn i wierszy (pozycji w obu wymiarach)?
b) Przykład: Wirtualna biblioteka szkolna. W bazie danych może być n (teoretycznie nieskończona liczba) czytelników i m (również teoretycznie nieskończona liczba) książek. Jeden użytkownik może jednocześnie wypożyczyć dowolną liczbę książek (koniecznie! - bo gdyby ilość książek była limitowana do określonej liczby to bym sobie z tym bez problemów poradził), a jedna książka może być jednocześnie wypożyczona przez wielu użytkowników (e-book). Administrator systemu, wchodząc na profil użytkownika (dowolnego) musi widzieć wszystkie książki, które on wypożyczył. Analogicznie - wchodząc na info o książce - chce widzieć wszystkich użytkowników, którzy w tej chwili mają ją wypożyczoną.
Jest to więc - jak ogólnie napisałem - tabela dwuwymiarowa o nieskończonej liczbie kolumn i rzędów. W kolumnach mam książki, w rzędach userów i stawiam sobie X przy każdym userze w tej kolumnie, którą książkę on ma. Nawet w Excelu dałoby się to zaimplementować, gdyby nie drobny zgrzyt - on też nie może mieć nieskończonej (lub bardzo dużej) liczby kolumn lub rzędów. Tym bardziej nie wiem - jak to zaimplementować w bazie danych MySQL.
c) Próba rozwiązania (nieudana?): Jeżeli zrobię jedną tabelę użytkowników (o kolumnach: id, imie, nazwisko, e-mail itd.) i drugą tabelę książek (id, autor, tytuł itd.) to jak przechowywać w tabeli użytkowników WSZYSTKIE identyfikatory aktualnie wypożyczonych książek, jeśli może być ich teoretycznie nieskończona ilość? Nie mogę w tabeli userów zrobić kolumn: ksiazka1, ksiazka2, ksiazka3 - bo chyba nie da się robić tabeli o nieskończonej liczbie kolumn. Ten sam problem dotyczy tabeli książek - nie mogę zrobić w niej kolumn user1, user2, user3 w których bym przechowywał id użytkowników mających aktualnie tą książkę, bo też może być ich teoretycznie nieskończona liczba.
Zastanawiałem się, czy nie rozwiązać tego jednym polem tekstowym. Tabela userów miałaby kolumnę typu tekstowego 'ksiazki' i tam zapisywałbym id każdej z wypożyczonych książek w postaci: "69|1|871|325|99" itd. Ale pole tekstowe również nie może być nieskończone (teoretycznie - bo w praktyce może być, ale przy bardzo długich polach tekstowych wydajność bazy danych spada na łeb), a poza tym - zabawa z polami tekstowymi w taki sposób zarżnie mi bazę jak marzenie, a wydajność będzie, jakby serwer stał na procku 486 sprzed 15 latu... Wyszukiwanie, sortowanie w czymś takim to masakra.
Pomyślałem więc, żeby stworzyć osobno tabelę użytkowników, osobno książek i w żadnej z nich nie przechowywać tych informacji, tylko stworzyć trzecią tabelę, która służyłaby jedynie do łączenia tych dwóch pozostałych tabel. Miałaby jedynie dwie kolumny: id_user i id_book i gdy każdy użytkownik "wypożyczyłby" nową książkę to do takiej tabeli dopisywany byłby nowy rekord: user o takim id ma książkę o takim id. Wówczas przeszukiwanie i sortowanie chyba byłoby szybkie, ale znowu boję się o wydajność bazy danych. Wystarczy, że tysiąc userów ma po tysiąc książek i w bazie "łączącej" mamy milion rekordów.
Gdyby ktoś miał jakiś pomysł lub dowolną sugestię to byłbym bardzo wdzięczny!
- trejder
- Posty: 197
- Z nami od: 20 stycznia 2005, 15:31
- Lokalizacja: Katowice
Przeglądarka: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2a1pre) Gecko/20081203 Minefield/3.2a1pre
(nie znam MySQL, może być inna składnia)
select a.nazwisko, a. imie
from USERZY a, KSIAZKI b
where b.user is not null
and a.id=b.user;
- dexter
- Moderator
- Posty: 8498
- Z nami od: 02 października 2004, 21:30
Przeglądarka: Mozilla/5.0 (Windows; U; Windows NT 5.1; pl; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4
dexter pisze:Nie do końca. Jedna książka może być wypożyczona przez tylko jednego usera. (...)
A, jeśli to e-book? Albo wybór x partii przez y wyborców? Dexter - wypożyczalnia i książki to tylko przykład. Ogólne zasady pozostają bez zmian. Dwuwymiarowa tabela (arkusz kalkulacyjny, krzyżówka), gdzie liczba kolumn i wierszy może być nieskończona (przynajmniej w teorii) lub dowolny inny sposób rozwiązania takiego zagadnienia, by dowolny z n rekordów z jednej tabeli można było powiązać z dowolną ilością rekordów z drugiej tabeli.
- trejder
- Posty: 197
- Z nami od: 20 stycznia 2005, 15:31
- Lokalizacja: Katowice
Przeglądarka: Mozilla/5.0 (Windows; U; Windows NT 5.1; pl; rv:1.9.1b3pre) Gecko/20081214 Shiretoko/3.1b3pre
trejder pisze:Pomyślałem więc, żeby stworzyć osobno tabelę użytkowników, osobno książek i w żadnej z nich nie przechowywać tych informacji, tylko stworzyć trzecią tabelę, która służyłaby jedynie do łączenia tych dwóch pozostałych tabel. Miałaby jedynie dwie kolumny: id_user i id_book i gdy każdy użytkownik "wypożyczyłby" nową książkę to do takiej tabeli dopisywany byłby nowy rekord: user o takim id ma książkę o takim id. Wówczas przeszukiwanie i sortowanie chyba byłoby szybkie, ale znowu boję się o wydajność bazy danych. Wystarczy, że tysiąc userów ma po tysiąc książek i w bazie "łączącej" mamy milion rekordów.
IMHO tylko w ten sposób da się to osiągnąć: tabela z użytkownikami, tabela z książkami i tabela z wypożyczeniami.
Co do wydajności to nie mam takiej wiedzy, żeby to ocenić ale chyba nie powinno być problemu. To tylko dwie kolumny, liczbowe.
Poza tym "tysiąc użytkowników ma po tysiąc książek" to raczej mocno przesadzone. Nawet 100 książek na użytkownika to wg mnie założenie zbyt na wyrost...
Co do tworzenia "krzyżówki": limit kolumn w bazie mySQL wynosi teoretycznie 4096 a może być mniejszy więc to jest jeszcze mniej elastyczne. Nie mówiąc oczywiście o problemie oprogramowania później bazy, której struktura zmienia się wraz z każdym dodaniem użytkownika/książki (zależy co by było w kolumnie).
- Leepa
- Posty: 281
- Z nami od: 09 grudnia 2004, 09:31
- Lokalizacja: Kraków
Przeglądarka: Mozilla/5.0 (Windows; U; Windows NT 5.1; pl; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4
Leepa pisze:Co do wydajności to nie mam takiej wiedzy, żeby to ocenić ale chyba nie powinno być problemu. To tylko dwie kolumny, liczbowe.
Poza tym "tysiąc użytkowników ma po tysiąc książek" to raczej mocno przesadzone. Nawet 100 książek na użytkownika to wg mnie założenie zbyt na wyrost...
Popełniasz ten sam błąd, co Dexter. Wypożyczalnia i książki to tylko ilustracja problemu, który dotyczy projektu nad którym pracuję, a którego szczegółów zdradzić nie mogę (zastrzeżenie klienta). Zapewniam Cię, że w mojej "wypożyczalni" każdy użytkownik może wypożyczyć nawet 10 000 "książek" i nie będzie ich w ogóle zwracał, więc odpada też pomysł z archiwizowaniem części bazy danych lub usuwaniem wpisów dotyczących "książek" oddanych - bo takich nie będzie.
Ogólnie chodzi o ideę - dwuwymiarowa tablica o nieskończonej (przynajmniej w teorii) liczbie kolumn i wierszy. Z Twojej odpowiedzi i z moich dalszych poszukiwań wynika, że rozwiązanie z trzecią tabelą to jedyne wyjście.
Leepa pisze:Co do tworzenia "krzyżówki": limit kolumn w bazie mySQL wynosi teoretycznie 4096 a może być mniejszy więc to jest jeszcze mniej elastyczne. Nie mówiąc oczywiście o problemie oprogramowania później bazy, której struktura zmienia się wraz z każdym dodaniem użytkownika/książki (zależy co by było w kolumnie).
Dlatego też rozwiązanie z dodawaniem n-kolumn w tabeli użytkowników odrzuciłem na samym początku.
- trejder
- Posty: 197
- Z nami od: 20 stycznia 2005, 15:31
- Lokalizacja: Katowice
Przeglądarka: Mozilla/5.0 (Windows; U; Windows NT 6.0; pl; rv:1.8.1.20) Gecko/20081217 Firefox/2.0.0.20
Pomyślałem więc, żeby stworzyć osobno tabelę użytkowników, osobno książek i w żadnej z nich nie przechowywać tych informacji, tylko stworzyć trzecią tabelę, która służyłaby jedynie do łączenia tych dwóch pozostałych tabel.
w podobny niezbyt dobry sposob zostal rozwizany problem czytania postow przez userow w forum phpbb i jak mozna sie przekonac to dziala dobrze tylko gdy liczba userow/postow forum jest mala.
Zastanawiałem się, czy nie rozwiązać tego jednym polem tekstowym. Tabela userów miałaby kolumnę typu tekstowego 'ksiazki' i tam zapisywałbym id każdej z wypożyczonych książek w postaci: "69|1|871|325|99" itd. (...)
Ta idea nie jest generalnie zła jeśli userowi nie zachce się wyporzyczyć pół miliona ksiazek...
Jeśli ja miałbym coś podobnego zrobić (mając do dyspozycji małą bazę danych) zrobilbym na FTP folder 'userzy' i pliki o nazwie IDusera. Do kazdego pliku dodawalbym w nowej linice IDksiazki.
Jeśli chodzi o baze danych to moze cos w stylu tabeli 3 wymiarowej? (gdzie "3 wymiar" to inna tabela
- Gość
Przeglądarka: Mozilla/5.0 (Windows; U; Windows NT 5.1; pl; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5
Anonymous pisze:Jeśli ja miałbym coś podobnego zrobić (mając do dyspozycji małą bazę danych) zrobilbym na FTP folder 'userzy' i pliki o nazwie IDusera. Do kazdego pliku dodawalbym w nowej linice IDksiazki.
Myślałem o tym. Odpada zupełnie. Wielokrotnie (na różnych serwerach i pod różną ich konfiguracją) miałem do czynienia z problemami na temat uprawnień jednoczesnego dostępu do pliku. PHP moim zdaniem traktuje to strasznie po macoszemu. Mimo zakładania (na pewno!) blokady, że w momencie zapisu żaden inny proces (użytkownik) nie ma dostępu do danego pliku to wielokrotnie zdarzało mi się, że pliki były wymazywane (zerowane), gdy PHP dopuścił jednoczesny odczyt i zapis mimo założonej blokady. Konsultowałem się na ten temat z różnymi adminami i wszędzie odpowiedź była taka sama - oficjalnie PHP nie powinien tego robić, a nieoficjalnie - zdarza się. Pliki tekstowe nie służą do zapisywania danych, które mogą zmieniać się bardzo często i szybko w jednostce czasu lub być zmieniane przez wielu użytkowników (procesów) jednocześnie.
Od tego czasu, nawet tak proste rzeczy, jak licznik odwiedzin robię na bazie MySQL mimo, że plik tekstowy nadawałby się do tego idealnie (jeśli liczy się globalnie tylko odwiedziny dla całego serwisu, a nie tylko dla jednej strony). Bo mimo, że do przechowywania jest tylko jedna wartość - nie raz zdarzało mi się zerowanie takiego tekstowego licznika.
Dzięki za pozostałe rady - rozważę je.
- trejder
- Posty: 197
- Z nami od: 20 stycznia 2005, 15:31
- Lokalizacja: Katowice
Kto jest online
Zarejestrowani użytkownicy: Baidu [Spider], Bing [Bot], Google [Bot]