[MySQL] Ograniczenia wielkości wstawianego wiersza do tabeli


(slepciu) #1

Witam

Mam bazę danych (MySQL), a w niej tabelę (InnoDB), która przechowuje informacje podane w ankiecie. Ankieta jest długa i ma sporo pól tekstowych. W sumie w tabeli jest ponad 40 pól typu text. Problem pojawia się kiedy ktoś wpiszę duże ilości tekstu w wiele pól w formularzu. Przykładowo, kiedy suma wpisanych znaków we wszystkie pola wynosi 14000, wówczas zapis się wysypuje komunikatem:

Co ciekawe jeśli nawet dłuższy tekst wpisze w jedno pole to zapisuje się bez problemu. Tak samo jeśli wpiszę teksty krótsze w różne pola. Jeden z testów pokazał mi, że mogę wpisać w 15 pól tekst po 500 znaków, przy poolu 16 już się wysypało.

Czy ktoś jest w stanie mi wyjaśnić na czym polega problem. Wnioskuję na tą chwilę, że chodzi o jakieś ograniczenie w ilości danych w jednym wierszu, ale nie mogę zrozumieć, ani odnaleźć w necie, jakiś informacji jak te ograniczenia wyglądają.


(Drobok) #2

Bo to nie jest wina mysql, tylko ograniczenia nałożonego przez serwer co do wielkości tablicy znaków ;]


(slepciu) #3

OK, a czy jesteś mi w stanie powiedzieć jak te ograniczenia wyglądają, albo jak je sprawdzić, ewentualnie zmienić. Dodam jeszcze, że taki sam błąd mam lokalnie i na hostingu.


(Drobok) #4

Aj, jednak to nie wina php, tylko mysql nie doczytałem ;]

To jednak limit innodb :expressionless:

http://www.mysqlperformanceblog.com/200 ... on-basics/

Spróbuj zmienić na MyISAM


(slepciu) #5

MyISAM mi nie pasuje ponieważ nie obsługuje kluczy obcych i transakcji, ale sprawdzę dla testu i dam znać. Nie wiem czy dam radę dzisiaj, bo mam inną pilną rzecz do zrobienia.

Jeśli chodzi o link, który podałeś to szczerze mówiąc niewiele mi wyjaśnia, bo za słabo znam angielski


(Drobok) #6

Optymalizacja pod tą bazę, tylko na hostingu nie da rady tego wykonać ;]


(Damgora) #7

Na pewno masz te pola typu TEXT?

http://dev.mysql.com/doc/refman/5.0/en/ ... tions.html

http://dev.mysql.com/doc/refman/5.0/en/ ... limit.html


(slepciu) #8

Dla rozwiania wątpliwości wklejam kod tworzący tabelę:

CREATE TABLE IF NOT EXISTS `ankieta` (

  `id_ankieta` INT NOT NULL AUTO_INCREMENT ,

  `data_dodania` DATETIME NOT NULL ,

  `data_edycji` DATETIME NOT NULL ,

  `stan_cywilny` TINYINT NULL COMMENT '0-samotna\n1-mezatka\n2-wdowa\n3-panna' ,

  `choroby_w_rodzinie` TEXT NULL ,

  `problemy_w_dziecinstwie` TEXT NULL ,

  `hormonalny` TEXT NULL ,

  `oczy_uszy` TEXT NULL ,

  `moczowy` TEXT NULL ,

  `oddechowy` TEXT NULL ,

  `nerwowy` TEXT NULL ,

  `depresja` TEXT NULL ,

  `leki` TEXT NULL ,

  `witaminy` TEXT NULL ,

  `zabiegi` TEXT NULL ,

  `alternatywna` TEXT NULL ,

  `psychoterapia` TEXT NULL ,

  `operacje` TEXT NULL ,

  `rany` TEXT NULL ,

  `szpital` TEXT NULL ,

  `mama_porod` VARCHAR(145) NULL ,

  `mama_wydarzenia` TEXT NULL ,

  `mama_choroba` TEXT NULL ,

  `mama_piers` TEXT NULL ,

  `rodzenstwo` TEXT NULL ,

  `ciaze` TEXT NULL ,

  `ciaza_problemy` TEXT NULL ,

  `ciaza_leki` TEXT NULL ,

  `karmienie` TEXT NULL ,

  `miesiaczka_pierwsza` VARCHAR(45) NULL ,

  `miesiaczka_zaburzenia` TEXT NULL ,

  `miesiaczka_hormony` TEXT NULL ,

  `miesiaczka_ostatnia` VARCHAR(45) NULL ,

  `miesiaczka_opis` TEXT NULL ,

  `antykoncepcja_preparaty` TEXT NULL ,

  `antykoncepcja_spirala` TEXT NULL ,

  `kobiece_leczenie` TEXT NULL ,

  `nieplodnosc_trudnosci` TEXT NULL ,

  `nieplodnosc_badania` TEXT NULL ,

  `nieplodnosc_leczenie` TEXT NULL ,

  `nieplodnosc_partner` TEXT NULL ,

  `htz_od_kiedy` VARCHAR(145) NULL ,

  `htz_jakie` VARCHAR(145) NULL ,

  `suplementy_diety` VARCHAR(145) NULL ,

  `nerwowa` TINYINT NULL ,

  `nerwowa_powod` TEXT NULL ,

  `stres` TINYINT NULL ,

  `praca` TINYINT NULL ,

  `partner` TINYINT NULL ,

  `wstawanie` TINYINT NULL ,

  `rodzice_relacje` TEXT NULL ,

  `zmienic_co` TEXT NULL ,

  `zmienic_mozliwosc` VARCHAR(100) NULL ,

  `bolesne_dos` TEXT NULL ,

  `cwiczenia_ile` VARCHAR(45) NULL ,

  `alergia_leki` VARCHAR(245) NULL ,

  `alergia_pokarm` VARCHAR(245) NULL ,

  `sniadanie` VARCHAR(245) NULL ,

  `obiad` VARCHAR(245) NULL ,

  `kolacja` VARCHAR(245) NULL ,

  `miedzy_posilkami` VARCHAR(245) NULL ,

  `rozwoj_osobisty` TEXT NULL ,

  `jak_myslisz` TEXT NULL ,

  `hobby` TEXT NULL ,

  `dolegliwosci` TEXT NULL ,

  `czy_eankieta` TINYINT NOT NULL DEFAULT 0 ,

  `id_pacjent` INT NOT NULL ,

  PRIMARY KEY (`id_ankieta`) ,

  INDEX `id_pacjent1` (`id_pacjent` ASC) ,

  CONSTRAINT `id_pacjent1`

    FOREIGN KEY (`id_pacjent` )

    REFERENCES `pacjent` (`id_pacjent` )

    ON DELETE CASCADE

    ON UPDATE CASCADE)

ENGINE = InnoDB

-- Dodane 12 września 2011, o 16:07 --

Trochę odświeżę. Miałem napisać wcześniej, ale nawał obowiązków nie pozwolił. Okazuje się że wstawiając pola typu TEXT też trafiamy na ograniczenia.

W zrozumieniu (choć niepełnym) pomogły mi te dwa linki:

http://dev.mysql.com/doc/refman/5.0/en/innodb-restrictions.html

http://bugs.mysql.com/bug.php?id=1611

oraz kilka innych stron, których już nie potrafię podać.

Poza ograniczeniem nałożonym na MySQL'a dodatkowe ograniczenie powoduje użycie kodowania UTF-8. Generalnie maksymalna ilość znaków wprowadzona w pola o Zmiennej długości może wynosić w takim przypadku 8 tysięcy z małym hakiem. Teoretycznie pola typu TEXT nie są wliczane w ten limit, ale okazuje się, że z każdego takiego pola jego początek jest wliczany, wg jednego z powyższych linków pierwsze 512 bajtów, ale z mich doświadczeń wynika że więcej (około 800), podejrzewam, że to wina kodowania.

Ostatecznie problem rozwiązałem dzieląc tabelę na kilka mniejszych.

WAŻNE: To co piszę wyżej jest czymś pośrednim między zdobytą wiedzą teoretyczną, a zdobytą metodą prób i błędów, dlatego tez nie mam pewności, czy to co napisałem jest w 100% prawdą. Nie miałem czasu żeby dalej drążyć temat. Może komuś to pomoże jak spotka podobny problem.