[MySQL] Rekurencja na InnoDB
Mariusz S. - 24-08-2007 00:00
[MySQL] Rekurencja na InnoDB
Witam,
próbuje zaprojektować tabelkę której klucz główny (idtest) połączony jest z kluczem obcym (ref_test) - rekurencja.
CREATE TABLE test ( idtest INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, ref_test INTEGER UNSIGNED NOT NULL, nazwa VARCHAR(20) NULL, PRIMARY KEY(idtest), INDEX test_index(ref_test), FOREIGN KEY(ref_test) REFERENCES test(idtest) ON DELETE CASCADE ON UPDATE CASCADE ) TYPE=InnoDB;
Zależy mi aby tabelka była typu InnoDB a referencja cascade.
No i wszystko pięknie, ale kiedy próbuje dodać rekord to z oczywistych względów wywala mi błąd.
INSERT INTO test VALUES (1, 0 ,'test 1'); INSERT INTO test VALUES (2, 1 ,'test 2'); INSERT INTO test VALUES (3, 2 ,'test 3');
Czy ktoś z grupowiczów wie jak rozwiązać powyższy problem?
-- Pozdrawiam Mariusz
Rafal sxat - 24-08-2007 00:00
> INDEX test_index(ref_test), > FOREIGN KEY(ref_test) > REFERENCES test(idtest) > ON DELETE CASCADE > ON UPDATE CASCADE > ) > TYPE=InnoDB; > > Zależy mi aby tabelka była typu InnoDB a referencja cascade. > > No i wszystko pięknie, ale kiedy próbuje dodać rekord to z oczywistych > względów wywala mi błąd. > > INSERT INTO test VALUES (1, 0 ,'test 1'); > INSERT INTO test VALUES (2, 1 ,'test 2'); > Czy ktoś z grupowiczów wie jak rozwiązać powyższy problem? >
zakladajac ze to dziala, mozna wylaczyc sprawdzanie integralnosci przez set check foreign keys
pozdrawiam Rafal sxat
(www.sxar.pl dziennik lekcyjny)
-- Archiwum grupy: http://niusy.onet.pl/pl.comp.bazy-danych
Wojciech Malinowski - 25-08-2007 00:00
Mariusz S. wrote: > Witam, > > próbuje zaprojektować tabelkę której klucz główny (idtest) połączony > jest z kluczem obcym (ref_test) - rekurencja.
Jak mawiają niektórzy - "żeby zrozumieć rekurencję musisz zrozumieć najpierw rekurencję". Jednym z jej wymagań jest, że musi mieć jakiś koniec. Tym końcem w tym przypadku będzie pierwszy element, który w ref_test będzie przechowywał NULL, a więc definicja kolumny jest błędna. Powinno być:
CREATE TABLE test ( idtest INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, ref_test INTEGER UNSIGNED NULL, [...]
a potem:
INSERT INTO test VALUES (1, NULL ,'test 1'); INSERT INTO test VALUES (2, 1 ,'test 2'); INSERT INTO test VALUES (3, 2 ,'test 3');
BTW Właśnie skończyłem czytać książkę Joela Spolsky'ego, w której pisze on, że większość ludzi urodziła się bez tej części mózgu, która pozwala zrozumieć rekurencję i wskaźniki. Myślałem, że to niemożliwe, a tu jednak.
Pozdrawiam, Wojciech Malinowski
Mariusz S. - 25-08-2007 00:01
To mi pojechałeś po ambicji )-: Zastanawiam się jak Ty mogłeś przeczytać tą książkę skoro masz problemy z przeczytaniem mojego posta ze zrozumieniem. Nie pytam się o samą rekurencję tylko o połączenie jej z referencją CASCADE typu InnoDB. Skoro przeczytałeś taką mądrą książkę to zapewne wiesz, że istnieją dużo lepsze i bardziej wydajne algorytmy do rozwiązania tego problemy. Po drugie zapewne wiesz (albo i nie), że wartość null jest różnie interpretowana w różnych systemach baz danych i odradza się jej stosowanie zwłaszcza w kluczach.
W poprzednim poście może dla niektórych wyraziłem się niejasno. Chodzi o to w jaki sposób łączycie dwa klucze w jednej tabelce aby móc przy pomocy jednego zapytania np:
delete from test where idtest=3;
usunąć wszystkie pozostałe rekordy połączone przez ref_test.
INSERT INTO test VALUES (1, 0 ,'test 1'); INSERT INTO test VALUES (2, 1 ,'test 2'); INSERT INTO test VALUES (3, 2 ,'test 3');
Rozwiązanie:
CREATE TABLE test ( idtest INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, ref_test INTEGER UNSIGNED NOT NULL, nazwa VARCHAR(20) NULL, PRIMARY KEY(idtest) );
mnie nie interesuje!!!
-- Pozdrawiam
=?ISO-8859-2?Q?Pawe=B3_Matejski?= - 25-08-2007 00:01
Mariusz S. wrote: > To mi pojechałeś po ambicji )-: > Zastanawiam się jak Ty mogłeś przeczytać tą książkę skoro masz problemy > z przeczytaniem mojego posta ze zrozumieniem. Nie pytam się o samą > rekurencję tylko o połączenie jej z referencją CASCADE typu InnoDB. > Skoro przeczytałeś taką mądrą książkę to zapewne wiesz, że istnieją dużo > lepsze i bardziej wydajne algorytmy do rozwiązania tego problemy. > Po drugie zapewne wiesz (albo i nie), że wartość null jest różnie > interpretowana w różnych systemach baz danych i odradza się jej > stosowanie zwłaszcza w kluczach. > > W poprzednim poście może dla niektórych wyraziłem się niejasno. > Chodzi o to w jaki sposób łączycie dwa klucze w jednej tabelce aby móc > przy pomocy jednego zapytania np: > > delete from test where idtest=3; > > usunąć wszystkie pozostałe rekordy połączone przez ref_test. > > INSERT INTO test VALUES (1, 0 ,'test 1');
No to jak chcesz wstawić ten rekord z odwołaniem do rekordu o idtest 0?
-- P.M.
Mariusz S. - 25-08-2007 00:01
>> INSERT INTO test VALUES (1, 0 ,'test 1'); > > No to jak chcesz wstawić ten rekord z odwołaniem do rekordu o idtest 0? > I właśnie tutaj jest problem. Dlatego szukam innego rozwiązania (-:
=?ISO-8859-2?Q?Pawe=B3_Matejski?= - 25-08-2007 00:01
Mariusz S. wrote: >>> INSERT INTO test VALUES (1, 0 ,'test 1'); >> >> No to jak chcesz wstawić ten rekord z odwołaniem do rekordu o idtest 0? >> > I właśnie tutaj jest problem. Dlatego szukam innego rozwiązania (-:
No i NULL jest rozwiązaniem. (Chyba, bo nie sprawdzałem). :)
-- P.M.
Wojciech Malinowski - 25-08-2007 00:01
Mariusz S. wrote: > To mi pojechałeś po ambicji )-:
Wcale nie chciałem Cię obrazić ani pojechać po ambicji.
> Po drugie zapewne wiesz (albo i nie), że wartość null jest różnie > interpretowana w różnych systemach baz danych i odradza się jej > stosowanie zwłaszcza w kluczach.
Projektuję bazy już od jakiegoś czasu i nigdy nie słyszałem o takiej regule. Czy mógłbyś przytoczyć jakieś źródło tej rewelacji? Kto odradza i dlaczego?
> Rozwiązanie: > > CREATE TABLE test ( > idtest INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, > ref_test INTEGER UNSIGNED NOT NULL, > nazwa VARCHAR(20) NULL, > PRIMARY KEY(idtest) > ); > mnie nie interesuje!!!
Przeczytaj jeszcze raz to co napisałem, bo zaproponowałem zupełnie coś innego. Zostaw swoje reguły ON DELETE i ON UPDATE ale usuń ograniczenie NOT NULL z ref_test.
Pozdrawiam, Wojciech Malinowski
Mariusz S. - 26-08-2007 00:05
Nie jest to o czym myślałem, ale działa. Wielkie dzięki (-:
A teraz pytanie troszkę z innej "beczki".
Dlaczego wykonanie procedury składowanej zrywa połączenie? Czy w moim kodzie jest coś nie tak czy to wina MySQL? <?php
$sql = new MySQLi('localhost','root','root','sklep'); $wynik = $sql->query('call test();');
while ($wiersz = $wynik->fetch_assoc()) { print_r($wiersz); } $wynik->close();
$wynik = $sql->query('select * from test;');
while ($wiersz = $wynik->fetch_assoc()) { print_r($wiersz); } $wynik->close();
$sql->close();
?>
zanotowane.pldoc.pisz.plpdf.pisz.pleffulla.pev.pl
|
[mysql] =?ISO-8859-2?Q?Za=E6mienie=2E=2E=2E_jak_wy=B6wietli=E6?==?ISO-8859-2?Q?=2E=2E=2E?=
[mysql] =?ISO-8859-2?Q?wielko=B6=E6_bazy_a_stabilno=B6=E6=2C?==?ISO-8859-2?Q?_podzia=B3_du=BFej_bazy_a_powi=B1zania_tabel?=
[MySQL] =?ISO-8859-2?Q?Wy=B6wietlenie_kolejnej_pozycji=2C_?==?ISO-8859-2?Q?jak=B1_mia=B3by_dany_rekord=2C_gdybym_czyta=B3 _?==?ISO-8859-2?Q?wg_konkretnych_kryteri=F3w=2E_Da_si=EA_=3F?=
[mysql 4.0.x] przenoszenie kolum =?ISO-8859-2?Q?mi=EAdzy_bazam?==?ISO-8859-2?Q?i_cd_=2E=2E=2E_?=
[MySQL] =?ISO-8859-2?Q?z=B3=B1czenie_tabeli_u=BFytkownik_i?==?ISO-8859-2?Q?_zdj=EAcia_z_wyborem_zdj=EAcia_domy=B6lnego?=
[MySQL] Jak =?ISO-8859-2?Q?wpisa=E6_do_tabeli_pozycje_dl?==?ISO-8859-2?Q?a_wierszy_gdybym_te_wiersze_wybiera=B3_w_ok?== ?ISO-8859-2?Q?re=B6lonej_kolejno=B6ci_=3F?=
Gdzie MySQL 4.1, a gdzie 5.0?
[MySQL 4.0...4.1] zabezpieczenie przed =?ISO-8859-2?Q?jednoczesn?==?ISO-8859-2?Q?=B1_edycj=B1?=
[MS SQL] "set names" (mySQL) w MS SQL
[mysql 5.x] jak =?ISO-8859-2?Q?zrealizowa=E6_zapytanie=3F_cz?==?ISO-8859-2?Q?yli_podzapytanie_i_wi=EAcej_ni=BF_jeden_rz=B1? ==?ISO-8859-2?Q?d_wynik=F3w?=
zanotowane.pldoc.pisz.plpdf.pisz.plred-hacjenda.opx.pl
Cytat
Decede mihi sole - nie zasłaniaj mi słonca. Gdy kogoś kochasz, jesteś jak stworzyciel świata - na cokolwiek spojrzysz, nabiera to kształtu, wypełnia się barwą, światłem. Powietrze przytula się do ciebie, choćby był mróz, a ty masz w sobie tyle radości, że musisz ją rozdawać wokoło, bo się w tobie nie mieści Hoc fac - tak czyń. A tergo - od tyłu; z tyłu. I czarne włosy posiwieją. Safona |
|