Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Kasowanie wierszy MySql - zrozumieć relacje
mys
post
Post #1





Grupa: Zarejestrowani
Postów: 7
Pomógł: 0
Dołączył: 1.10.2005

Ostrzeżenie: (0%)
-----


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.
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 5)
mhs
post
Post #2





Grupa: Zarejestrowani
Postów: 764
Pomógł: 3
Dołączył: 30.04.2003

Ostrzeżenie: (0%)
-----


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.
Go to the top of the page
+Quote Post
mike
post
Post #3





Grupa: Przyjaciele php.pl
Postów: 7 494
Pomógł: 302
Dołączył: 31.03.2004

Ostrzeżenie: (0%)
-----


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.
Go to the top of the page
+Quote Post
mys
post
Post #4





Grupa: Zarejestrowani
Postów: 7
Pomógł: 0
Dołączył: 1.10.2005

Ostrzeżenie: (0%)
-----


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?
Go to the top of the page
+Quote Post
mike
post
Post #5





Grupa: Przyjaciele php.pl
Postów: 7 494
Pomógł: 302
Dołączył: 31.03.2004

Ostrzeżenie: (0%)
-----


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.
Go to the top of the page
+Quote Post
mys
post
Post #6





Grupa: Zarejestrowani
Postów: 7
Pomógł: 0
Dołączył: 1.10.2005

Ostrzeżenie: (0%)
-----


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.
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 24.08.2025 - 08:11