Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Kasowanie wierszy MySql - zrozumieć relacje
Forum PHP.pl > Forum > Bazy danych
mys
Witam

Stworzyłem bazę składającą się z dwóch tabeli:

mysql> select * from fv;
+----+-----------+
| id | nr_dok |
+----+-----------+
| 1 | fv/1/2005 |
| 2 | fv/2/2005 |
+----+-----------+
2 rows in set (0.04 sec)

mysql> select * from rzecz;
+----+-----------+---------+
| id | nazwa | faktura |
+----+-----------+---------+
| 1 | antena | 1 |
| 2 | kabel | 1 |
| 3 | zlaczka N | 2 |
| 4 | antena | 2 |
+----+-----------+---------+
4 rows in set (0.04 sec)

Istnieje relacja 1-wielu, między nr_dok, a nazwa w tabeli rzecz. Np. fv/2/2005 jest powiązana z 'zlaczka N' i 'antena' w tabeli rzecz co wskazuje '2' z kolumny 'faktura'. 'id' w obydwu tabelach są kluczami głównymi, kolumna 'faktura' kluczem obcym.

Czy dobrze zaprojektowałem tą prostą bazę jeśli występuje relacja jak wyżej opisałem?

Chcę skasować 'fv/2/2005' i w konsekwencji powiązane z nimi wiersze 3 i 4 z tabeli rzecz. W jaki sposób to osiągnąć nie stosując wartości klucza? Np. DELETE RFOM rzecz WHERE faktura = 2; nie chcę użyć, bo skąd będę wiedział, że to akurat numer 2, a nie inny.

Staram się zrozumieć zastosowanie kluczy i relacji, ale chyba nie bardzo mi się to udaje. Stoje na początku drogi zwanej SQL. Z góry dziękuje za wszelkie wyjaśnienia.
mhs
OK, moje uwagi:
- proponuję trochę lepsze nazewnictwo tabel
- generalnie jeżeli pomiędzy tabelami zachodzi relacja to nazwy pól w jednej i drugiej tabeli powinny być takie same (czyli nazwa klucza głównego w tabeli podstawowej powinna być taka sama jak nazwa klucza obcego w tabeli związanej)

Cytat
Czy dobrze zaprojektowałem tą prostą bazę jeśli występuje relacja jak wyżej opisałem?


Prawdę powiedziawszy nie wiele powiedziałeś o projekcie bazy danych i do końca nie można powiedzieć czy jest ona prawidłowo zaprojektowana. Jednak wydaje mi się, że można ją uznać za prawidłowo zaprojektowaną.


Cytat
Chcę skasować 'fv/2/2005' i w konsekwencji powiązane z nimi wiersze 3 i 4 z tabeli rzecz. W jaki sposób to osiągnąć nie stosując wartości klucza? Np. DELETE RFOM rzecz WHERE faktura = 2; nie chcę użyć, bo skąd będę wiedział, że to akurat numer 2, a nie inny.


By skasować rekordy z jednej i drugiej tabeli musisz znać klucz główny tabeli podstawowej czyli wydasz polecenie
  1. DELETE
  2. FROM nazwaTabeli WHERE f_id = X

a następnie usunać wszystkie rekordy w tabeli związanej czyli
Cytat
DELETE FROM nazwaDrugiejTabeli WHERE f_id = X

By upewnić się, że operacja zostanie wykonana prawidłowo możesz zastosować tzw. transakcje lub też zastosować tzw. kaskadowe usuwanie rekordów (wcześniej czy później poznając bazy danych trafisz na te pojęcia).


Cytat
Staram się zrozumieć zastosowanie kluczy i relacji, ale chyba nie bardzo mi się to udaje. Stoje na początku drogi zwanej SQL. Z góry dziękuje za wszelkie wyjaśnienia.


Polecam bardzo (przynajmniej ja tak uważam) dobrą książkę pt. Bazy danych nie tylko dla orłów (lub podobny temat) która jest napisana bardzo uniwersalnie (wszystko co w niej jest opisywane dotyczy niemal każdego systemu zarządzania bazą danych), a na pewno już zrozumiesz relacyjne bazy danych. Osobiście polecam.

Pozdrawiam i życze powodzenia.
mike
Podtrzymuję uwagi co do nazw.
Ponadto:

1. Dla tabeli rzecz załóz index na pole które jest kluczem obcym z tabeli fv ( czyli na faktura ):
  1. ALTER TABLE `rzecz` ADD INDEX ( `faktura` )


2. Potem dla tabeli rzecz łącze z tabelą fv typu:
(`faktura`) REFER `id/fv`(`id`) ON DELETE CASCADE

Wtedy jak usuniesz rekord z tabeli fv zwykłym DELETE to automatycznie usunięte zostaną rekordy z tablei rzecz powiązane z usuwany rekordem.
mys
Dziękuje serdecznie Wam za podpowiedzi. Właśnie doczytałem o: INNODB, FOREIGN KEY, REFERENCES i ON DELETE CASCADE.

Niestety mysql, do którego mam dostęp nie obsługuje tabel INNODB, a więc mechanizm kaskadowego usuwania danych z tabel odpada.

Może istnieje jakaś funkcja w mysql, która z tabeli nadrzędnej odczyta mi numer klucza (ten nieszczęsny klucz X)? Wydaje mi się, że tylko tego mi do szczęścia brakuje by usunąć powiązane z danym kluczem X, rekordy w tabeli podrzędnej.

Może php mógłby pomóc? Albo jakiś chwyt nie korzystający z transakcji?
mike
Pozostaje Ci:
  1. <?php
  2.  
  3. $intItemId = 12;
  4.  
  5. mysql_query( 'DELETE FROM fv WHERE id = ' . $intItemId );
  6.  
  7. if( mysql_affected_rows() > 0 )
  8. {
  9.  mysql_query( 'DELETE FROM rzecz WHERE faktura = ' . $intItemId );
  10. }
  11.  
  12. ?>


Nic więcej nie poradzisz :/

Zainstaluj sobie MySQL'a 4.1 i bedziesz miał wszystko czego Ci trzeba na obecnym etapie.
mys
Wydaje się, że rozwiązałem problem uzyskania numeru id klucza na podstawie pola nr_dok z tabeli fv. Zakładam, że wartości w polach nr_dok są unikalne.

Po:

SELECT @nr_id := id FROM fv WHERE nr_dok = 'fv/1/2005';

otrzymuje:

+--------------+
| @nr_id := id |
+--------------+
| 1 |
+--------------+

Polecenie:

DELETE FROM rzecz WHERE @nr_id = faktura;

usunie powiązane wiersze nr 1 i 2 z tabeli rzecz o co mi chodziło.
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.