większa wydajność - jedna tabela czy wiele ?

0

Witam,

Projektuję bazę danych do przyjmowania zgłoszeń o naprawie sprzętu i mam takie dane:

  • dane personalne klienta (imię,nazwisko,pesel, adres,etc)
  • dane dotyczące naprawianego sprzętu (model, marka, numer seryjny)
  • oraz jakieś inne opcje

Mogę stworzyć jedną tabelę, np "zgloszenia" i tam przechowywać wszystkie dane, jednak, czy takie postępowanie jest optymalne ?
Czy bardziej opłaca się tworzyć dwie tabele: "klienci", "zgloszenia" ?

0

Stwórz tabelę zgłoszenia:

  • ID klienta
  • ID sprzętu
  • data zgłoszenia
  • data wykonania (może być null -> wtedy nie zakończona sprawa jeszcze)
0

tak, tak czym więcej tabel z mniejszą ilością kolumn, tym szybciej będzie działać. Zachowanie szczegółowych danych przechowywać proponuje w innych tabelach za pomocą relacji :
Dala Twojej bazy danych np:

kraje
  id PK
  nazwa_kraj

adresy 
  id  PK
  ulica 
  kod
  miasto
  kraj_id FK

-- utworzenie klucza obcego z referencją do tab. kraji
ALTER TABLE adresy 
ADD FOREIGN KEY (kraj_id)
REFERENCES kraje(id);

klienci
  pesel PK
  imię
  nazwisko
  adres_id FK

-- utworzenie klucza obcego z referencją do tab. adresy
ALTER TABLE klienci
ADD FOREIGN KEY (adres_id )
REFERENCES adresy(id);

urzadzenia
  numer_seryjny PK
  model 
  marka 

zgloszenia
  ID PK
  ID_klienta FK
  ID_urzadzenia FK
  data zgłoszenia
  data wykonania

ALTER TABLE zgloszenia
ADD FOREIGN KEY (ID_klienta)
REFERENCES klienci(pesel);


ALTER TABLE zgloszenia
ADD FOREIGN KEY (ID_urzadzenia)
REFERENCES urzadzenia(numer_seryjny)

Czyli ja proponuje nawet więcej niż 2 tabele :)

0

@kasiaKasia napisała:

tak, tak czym więcej tabel z mniejszą ilością kolumn, tym szybciej będzie działać

no dobrze, ale kiedy będę chciał wyciągnąć dane to będę musiał je łączyć (JOIN), czy to nie spowolni działania systemu ?

np, jeśli będę chciał wyświetlić dane zlecenia o ID: 432, to:

  • biorę wszystko z tabeli "zlecenia" o ID = 432,
  • biorę wszystko z tabeli "klienci" o ZLECENIE_ID = 432
  • biorę wszystko z tabeli "sprzet" o ZLECENIE_ID = 432
  • etc

ogólniej, w systemie występuje relacja JEDEN - JEDEN, jednemu klientowi odpowiada jedno zlecenie oraz jeden sprzęt, etc

0

@lelas a szukanie w gigantycznej tabeli nie będzie spowalniać systemu? ;)
Bedziesz łaczył te tabele po kluczach, a na nich defaultowo masz indeksy, więc nie martw się o szybkość szukania i łączenia tego.

0

Niestety JOINy zabijają wydajność przy bazach o rozmiarach wielu gigabajtów czy tam terabajtów. Google tego doświadczyło i zrobiło własną nierelacyjną bazę danych BigTable, która zmiata wszystkie relacyjne bazy. Drugie "niestety" to to, że BigTable i podobne wymagają zmiany podejścia do projektowania bazy danych.

ATSD:
W pewnej firmie (nazwy nie muszę podawać) pewien lider projektu zastanawiał się co będzie szybsze:

  • wybór z dwóch baz o rozmiarze n/ 2,
  • wybór z jednej bazy o rozmiarze n,

Nietrudno się domyśleć, że przypadek pierwszy będzie praktycznie dwa razy wolniejszy. Wszystko dzięki temu, że indeksy zapewniają dostęp w czasie logarytmicznym - a więc jeśli mamy obecnie np 4 dostępy i rozgałęzienie B-drzewa w bazie o poziomie 100, to zwiększenie rozmiaru bazy 100 razy zwiększy ilość dostępów do 5. Chodzi mi o dostępy do dysku przy wyszukiwaniu jednego konkretnego rekordu za pomocą jednego indeksu.

0

@Shalom wsumie, to masz rację,
dzięki za pomoc

0

mam jeszcze parę pytań co do bazy, otóż wzorując się na powyższym przykładzie w moim przypadku byłoby tak:

	klienci(id,imie,nazwisko,adres);
	kamery(id,marka,model,nr_ser);
	zgloszenia(id, data_przyjecia, data_wykonania, opis_usterki, klient_id, kamera_id);

pól jest oczywiście trochę więcej, ale nie będę wszystkiego pisał.

Korzystając z CodeIgnitera, napisze do każdej tabeli osobny model, etc.

Dodawanie wpisów wygląda tak:

INSERT INTO `klienci` (`imie`,`nazwisko`,`adres`) VALUES 
	('Jan','Kowalski','Głucha 23'), //id=1 
	('Adam','Nowak','Ślepa 54'), //id=2
	('Krystyna','Nowak','Kulawa 91'); //id=3

INSERT INTO `kamery` (`marka`,`model`,`nr_ser`) VALUES
	('Panasonic','LT-2312','3298239'), //id=1
	('Sony','NX-4323','329128329'), //id=2
	('Olympus','ST-3291','329128493'); //id=3

INSERT INTO `zgloszenia` (`data_przyjecia`,`data_wykonania`,`opis_usterki`,`klient_id`,`kamera_id`) VALUES
	('2011-01-23','2011-02-01','uszkodzona matryca', 1,1), //id=1
	('2011-01-31','2011-02-03','uszkodzony wyświetlacz',2,2), //id=2
	('2011-02-14','2011-02-19','kamera się nie włancza',3,3); //id=3

w powyższym kodzie widać, że klienta o id=1 dotyczy kamera o id=1 i zgloszenie o id=1, i tak będzie zawsze, bo każde nowe zgłoszenie dodaje nowego klienta, kamerę i ogólnie zgłoszenie.
I teraz pytanie, czy to jest dobrze rozwiązane ? nie lepiej by było, gdybym np w klienci i kamery jako id (będące kluczem głównym) przemianował je na klucz obcy do zgłoszenia ? tzn:

	klienci(zgloszenie_id, // FK
		imie,nazwisko,adres);

	kamery(zgloszenie_id, // FK
		marka,model,nr_ser);

	zgloszenia(id, // PK
		 data_przyjecia, data_wykonania, opis_usterki, klient_id, kamera_id);

proszę o radę, pozdrawiam

0

Nie kombinuj bo widzę że słabo znasz się na bazach danych. Zrób osobne tabele dla klientów, kamer i zgłoszeń. W tabeli zgłoszenia klucze obce do klientów i kamer. Unikniesz w ten sposób nadmiarowości danych, czyli jednej z głównych idei baz relacyjnych.

0

@MiL napisał:

Unikniesz w ten sposób nadmiarowości danych

jakiej nadmiarowości? Chodzi właśnie oto, że jedna dodana kamera nie będzie mogła być wykorzystana przez innego klienta (poza tym, kamera ma nr seryjny, a ten jest unikatowy prawda?), i tak samo z klientem, raz dodany klient, aby mógł dodać nowe zgłoszenie, będzie musiał dodać swoje dane na nowo, etc

pytam tylko jak to optymalnie rozwiązać..
pozdrawiam KL.

0

No właśnie, jeżeli ten sam klient będzie miał nowe zgłoszenie to jego dane będą w bazie 2 razy. To bez sensu. Ale to twoja baza i zrobisz jak chcesz.

1 użytkowników online, w tym zalogowanych: 0, gości: 1