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

Odpowiedz Nowy wątek
fufekn
2011-02-13 19:13
fufekn
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" ?

Pozostało 580 znaków

2011-02-13 19:47

Rejestracja: 11 lat temu

Ostatnio: 4 lata temu

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)

Pozostało 580 znaków

2011-02-13 20:17

Rejestracja: 9 lat temu

Ostatnio: 2 lata temu

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 :)


edytowany 1x, ostatnio: kasiaKasia, 2011-02-13 20:30

Pozostało 580 znaków

2011-02-13 20:35

Rejestracja: 9 lat temu

Ostatnio: 8 lat temu

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

nie wiedziałam, że JOIN spowalnia :( - kasiaKasia 2011-02-13 22:07

Pozostało 580 znaków

2011-02-13 21:06
Moderator

Rejestracja: 16 lat temu

Ostatnio: 4 godziny temu

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.


Masz problem? Pisz na forum, nie do mnie. Nie masz problemów? Kup komputer...

Pozostało 580 znaków

2011-02-13 21:24

Rejestracja: 15 lat temu

Ostatnio: 5 minut temu

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.


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.
edytowany 1x, ostatnio: Wibowit, 2011-02-13 21:29

Pozostało 580 znaków

2011-02-13 21:29

Rejestracja: 9 lat temu

Ostatnio: 8 lat temu

0

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

Pozostało 580 znaków

2011-02-14 19:41

Rejestracja: 9 lat temu

Ostatnio: 8 lat temu

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

Pozostało 580 znaków

MiL
2011-02-15 12:08
MiL

Rejestracja: 14 lat temu

Ostatnio: 2 miesiące temu

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.

Pozostało 580 znaków

2011-02-15 12:53

Rejestracja: 9 lat temu

Ostatnio: 8 lat temu

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.

Pozostało 580 znaków

MiL
2011-02-15 13:28
MiL

Rejestracja: 14 lat temu

Ostatnio: 2 miesiące temu

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.

Pozostało 580 znaków

Odpowiedz

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