Tworzenie tabel MySQL vs PostgreSQL 2007-03-28
Tak się składa, że musiałem ostatnio wrócić na chwilę do MySQL i nie obyło się niestety bez problemów. Przede wszystkim raził mnie brak informacji co się dzieje. Przy zakładaniu tabel w PostgreSQL zawsze mamy komunikaty, że został utworzony klucz, że to, że tamto. W MySQL na odwrót, co byśmy nie robili komunikatów brak, a do tego zdarzają się w stylu "nie udało się".
Posiadałem dwie tabele w PostgreSQL i chciałem je zamienić na MySQL.
Zamieniłem cudzysłów (") na apostrof odwrócony (`) i wrzuciłem do MySQL. W pomocy wyczytałem, że CHECK jest ignorowane (The CHECK clause is parsed but ignored by all storage engines.), ale niestety tyldy (~) to niedotyczy. Inne znaki typu równość, nierówność, większe, itp. przepuszcza.
System natomiast nie poinformował, że nie utworzył więzów integralności. Wina jak się zdaje domyślnego typu tabeli MyISAM. Zmiana na InnoDB też nie pomogła. Dalej nie było powiązań ani komunikatów. Jak się okazuje MySQL lubi ignorować (For other storage engines, MySQL Server parses and ignores the FOREIGN KEY and REFERENCES syntax in CREATE TABLE statements.). Wniosek: klucze obce należy umieszczać na końcu definicji tabeli.
SERIAL w MySQL jest aliasem do BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE. Tylko wiąże się z tym problem, gdyż po zastosowaniu z PRIMARY KEY, UNIQUE też jest zakładane, a jak wiemy PRIMARY KEY i tak wymusza unikatowość zmiennej. Komunikat ostrzegający o tej anomalii wyświetlił mi się w phpMyAdmin. W PostgreSQL nawet jeśli damy PRIMARY KEY i UNIQUE to nie założy tego UNIQUE.
Z uwagi na to, że SERIAL tworzy bigint unsgined nie zgadzały mi się typy zmiennych w więzach integralności. Dostawałem komunikat, który nic nie mówił konkretnego: #1005 - Can't create table './hyh_test/users.frm' (errno: 150) .
Osateczny wygląd tabel w MySQL.
Postanowiłem także zmienić trochę tabele w PostgreSQL by były składniowo jak najbardziej podobne do tych z MySQL, dzięki czemu będzie łatwiej zmienić.
Ironio losu. Na serwerze został jednak zainstalowany dodatkowo PostgreSQL. Hip, hip! Hura! Hura! Hura! :)
Testowane na MySQL 5.0.24a i PostgreSQL 8.1.
Słowa kluczowe: PostgreSQL, Techblog, bazy danych, mysql, sql, tworzenie tabel, artykuł, blog
No cóż w MySQL takie "pierdoły" jak więzy integralności i transakcje są chyba wciąż traktowane po macoszemu... No cóż, najważniejsze żeby prosty SELECT na prostej tabeli "worek na dane" działał jak najszybciej... w końcu tego przeciętny developer LAMP chce...
Jajcuś: to niech przeciętny developer LAMP zastosuje SQLite zamiast MySQL, bo jako "worek na dane" działa szybciej niż MySQL
Grzechu: jasne... ale SQLite nie jest na "M" więc do " LAMP" się nie nadaje ;-)
Innymi słowy: "wszyscy" używają PHP i MySQL, no to każdy się za to zabiera...
A swoją drogą, to SQLite obsługuje transakcje w domyślnej konfiguracji to chyba od zawsze. Gorzej z więzami integralności (nawet FOREIGN KEY nie działa).
No i SQLite nie radzi sobie z jednoczesnym dostępem wielu klientów... a więc do aplikacji WWW niespecjalnie się nadaje.
Mozna w SQLite "zrobic" FK. A do Aplikacji WWW sie nadajke, zalezy tylko do jakiej. Tam gdzie trzeba duzo czytac i malo pisac do DB, jak najbardziej sie nadaje.
Czepię się tylko do jednego fragmentu:
"[...] gdyż po zastosowaniu z PRIMARY KEY, UNIQUE też jest zakładane, a jak wiemy PRIMARY KEY i tak wymusza unikatowość zmiennej.[...] W PostgreSQL nawet jeśli damy PRIMARY KEY i UNIQUE to nie założy tego UNIQUE."
To tak jak z Windows: można mu mówić, że się chce jabłko, a on i tak sądzi że wie lepiej i da Ci banana. To akurat zachowanie jest dużo lepsze w MySQL.
MySZ: jaki jest w takim razie sens tworzenia jednocześnie PRIMARY KEY i UNIQUE?
Nie ma sensu, i siłowe dokładanie tam UNIQUE jest błędem IMO (ale może jest ciut więcej w dokumentacji, trzeba by zajrzeć). Mi chodziło o to, że pgsql ignoruje jakąś dyrektywę, a mysql głośno krzyczy że nie jest to właściwe.
Nie, nie krzyczy. Dodaje takie coś bez szmeru. W phpMyAdmin takie coś mi się wyświetliło, a jest to skrypt zewnętrzny.
A, kurczę... pomerdało mnie się, rzeczywiście nie krzyczy - nie sprawdziłem od razu, a zasugerowałem się tylko tym co napisałeś :) Faktycznie, mysql sam z siebie nic nie krzyczy :)
To, że MySQL brakuje niektórych rzeczy, nie znaczy, że tylko służy dzieciom do pierwszych stron.
Wiele dużych serwisów działa bazując na LAMP.
Chwala autorowi tego artykułu!! Meczylem sie caly dzien i zastanawialem sie co jest nie tak z moim zapytaniem w mysql i dlaczego foreign key nie dziala, a okazalo sie ze to przez komende SERIAL. Ten artykuł jest bezcenny. DZIEKI WIELKIE !! :)
Gdybyście uważali trochę bardziej na wykładach z baz danych to byście się dowiedzieli, że klucz może być złożony z kilku kolumn, dzięki czemu każda z nich osobno nie musi być unikalna. Jeżeli chcemy jednak w którejś z nich taką unikalność zachować, stosujemy wtedy UNIQUE
W MySQL serial jest aliasem dla też dla UNIQUE. ponieważ AUTO_INCREMENT może być _tylko_ na kluczach unikalnych (Primary też jest unikalny).
@MySZ IMO nie jest lepsze, redundancja danych w bazach to chyba zła rzecz, nie?
@Ex a to do kogo?