W MySQL, jeśli utworzę nowe VARCHAR(32)pole w tabeli UTF-8, czy oznacza to, że mogę przechowywać 32 bajty danych w tym polu lub 32 znaki (wielobajtowe)?
MySQL interpretuje specyfikacje długości w definicjach kolumn znakowych w jednostkach znakowych. (Przed MySQL 4.1 długości kolumn były interpretowane w bajtach). Dotyczy to typów CHAR, VARCHAR i TEXT.
Co ciekawe (nie myślałem o tym) utf8 wpływa na maksymalną długość kolumny varchar w następujący sposób:
Efektywna maksymalna długość VARCHAR w MySQL 5.0.3 i nowszych jest zależna od maksymalnego rozmiaru wiersza (65 535 bajtów, który jest wspólny dla wszystkich kolumn) i używanego zestawu znaków. Na przykład znaki utf8 mogą wymagać do trzech bajtów na znak, więc kolumna VARCHAR, która używa zestawu znaków utf8, może mieć maksymalnie 21 844 znaków.
M Brown, dzięki za wspomnienie o tym. Pole VARCHAR (10) (przy użyciu utf8mb4) może przechowywać „💩💩💩💩💩💩💩💩💩💩” (10 stosów poo), czyli 10 znaków, ale 40 bajtów.
basic6
3
To. To jedyna prawidłowa odpowiedź. Zbyt wiele osób uważa, że zachowanie wersji 4 jest ewangelią.
Brendan Byrd,
2
Zaakceptowana odpowiedź jest również poprawna dla MySQL 5 - wstawione liczby były w rzeczywistości częścią zestawu znaków o pełnej szerokości i są wielobajtowymi znakami unicode, jak również wspomniał na plakacie, że wstawił „32 wielobajtowe dane”. Szkoda, że tak wielu ludzi źle zrozumiało.
user193130
Powołując się na następujące źródło, uważam, że znak utf8 wymaga obecnie do 6 bajtów, czyli od 1 do 6 bajtów. To powoduje, że w najgorszym przypadku maksymalna liczba znaków to 10922. Myślę. joelonsoftware.com/articles/Unicode.html
Aby zaoszczędzić miejsce dzięki UTF-8, użyj VARCHAR zamiast CHAR. W przeciwnym razie MySQL musi zarezerwować trzy bajty dla każdego znaku w kolumnie CHAR CHARACTER SET utf8, ponieważ jest to maksymalna możliwa długość. Na przykład MySQL musi zarezerwować 30 bajtów dla kolumny CHAR (10) CHARACTER SET utf8.
Prawie nigdy nie używam, CHARa kiedy to robię, nie jest to przeznaczone do przechowywania znaków wielobajtowych, więc jestem bezpieczny. A co z tym VARCHAR, czy na pewno limit jest zdefiniowany w znakach wielobajtowych, a nie w znakach jednobajtowych?
Alix Axel
9
@jspcal: UTF-8 wykorzystuje maksymalnie 4 bajty na znak, a nie 3. A może MySQL nie obsługuje wszystkich 4 bajtów?
W standardzie UTF-8 znaki ASCII będą przechowywane tylko w jednym bajcie - aby naprawdę to przetestować, musisz faktycznie użyć kilku znaków wielobajtowych (tj. Innych niż ascii) w swoim żądaniu testowym.
rjmackay
5
To jest złe, przynajmniej w przypadku MySQL 5+. Podczas określania rozmiaru kolumny dla varchar lub char, jest on określany w postaci znaków. Uważam, że rzeczywisty rozmiar kolumny VARCHAR (32) wyniósłby 32x3 + 1 = 97 bajtów.
Wstawiłem 40 znaków Unicode do DB i zostałem obcięty do 32 znaków. Ale wygląda na to, że ludzie myślą, że użyłem bajtów ascii i zostałem obcięty do 32 bajtów. Nic dziwnego, mam głosy negatywne, lol.
TY
2
@ButtleButkus "Uważam, że rzeczywisty rozmiar kolumny VARCHAR (32) wyniósłby 32x3 + 1 = 97 bajtów" Byłoby, gdybyś używał utf8, ale wtedy otrzymujesz zepsutą obsługę Unicode w MySQL. Zamiast tego powinieneś użyć utf8mb4kodowania, ponieważ istnieje maks. 4 bajty w znaku utf-8 , a nie 3, jak w wariancie utf8 w MySQL ...
Stijn de Witt
1
Lepiej jest używać znaku „char” w przypadku często aktualizowanych tabel, ponieważ całkowita długość danych wiersza zostanie ustalona i szybka. Kolumny Varchar sprawiają, że rozmiary danych wierszy są dynamiczne. To nie jest dobre dla MyISAM, ale nie wiem o InnoDB i innych. Na przykład, jeśli masz bardzo wąską kolumnę „typ”, może być lepiej użyć znaku char (2) z zestawem znaków latin1, aby zająć tylko minimalną ilość miejsca.
Czytałem, że jeśli DOWOLNA kolumna w tabeli to varchar, tracisz wszystkie korzyści płynące z posiadania kolumn typu char. Zasadniczo wydaje się, że aby uzyskać maksymalne korzyści, musisz wybrać wszystkie varchar lub wszystkie char w tabeli. Nie wiem jednak, czy to prawda.
Buttle Butkus
Dla MyISAM jest kilka argumentów za CHAR. W przypadku InnoDB dzieje się tak wiele innych rzeczy, że debata „dynamiczny / stały rozmiar wiersza” jest zasadniczo nieistotna.
Rick James
IMHO ważną kwestią jest to, że w przypadku bardzo małych długości może być korzystne użycie CHAR.
ToolmakerSteve
0
Jeśli połączysz się z bazą danych przy użyciu kodowania latin1 (na przykład z PHP), aby zapisać ciąg PHP UTF8 w kolumnie MySQL UTF8, będziesz mieć podwójne kodowanie UTF8.
Jeśli łańcuch UTF8 $sma 32 znaki, ale 64 bajty, a kolumna ma VARCHAR(32)format UTF8, podwójne kodowanie spowoduje konwersję ciągu $sna 64-znakowy ciąg UTF8, który zostanie obcięty w bazie danych do jego 32 pierwszych znaków odpowiadających 32 pierwszym bajtom z $s. Możesz pomyśleć, że MySQL 5 zachowuje się jak MySQL 4, ale w rzeczywistości jest to druga przyczyna tego samego efektu.
Odpowiedzi:
Ta odpowiedź pojawiła się u góry moich wyników wyszukiwania Google, ale nie była poprawna, więc:
Zamieszanie jest prawdopodobnie spowodowane testowaniem różnych wersji mysql.
http://dev.mysql.com/doc/refman/5.0/en/string-type-overview.html
Co ciekawe (nie myślałem o tym) utf8 wpływa na maksymalną długość kolumny varchar w następujący sposób:
źródło
utf8mb4
) może przechowywać „💩💩💩💩💩💩💩💩💩💩” (10 stosów poo), czyli 10 znaków, ale 40 bajtów.pozwoliłoby ci to zapisać 32 wielobajtowe znaki
http://dev.mysql.com/doc/refman/5.0/en/charset-unicode.html
źródło
CHAR
a kiedy to robię, nie jest to przeznaczone do przechowywania znaków wielobajtowych, więc jestem bezpieczny. A co z tymVARCHAR
, czy na pewno limit jest zdefiniowany w znakach wielobajtowych, a nie w znakach jednobajtowych?32 wielobajtowe dane
varchar(32)
z sortowaniemutf8_unicode_ci
, właśnie przetestowałem z XAMPP.Skróć do:
Pamiętaj, że nie są to zwykłe znaki ASCII.
źródło
utf8
, ale wtedy otrzymujesz zepsutą obsługę Unicode w MySQL. Zamiast tego powinieneś użyćutf8mb4
kodowania, ponieważ istnieje maks. 4 bajty w znaku utf-8 , a nie 3, jak w wariancie utf8 w MySQL ...Lepiej jest używać znaku „char” w przypadku często aktualizowanych tabel, ponieważ całkowita długość danych wiersza zostanie ustalona i szybka. Kolumny Varchar sprawiają, że rozmiary danych wierszy są dynamiczne. To nie jest dobre dla MyISAM, ale nie wiem o InnoDB i innych. Na przykład, jeśli masz bardzo wąską kolumnę „typ”, może być lepiej użyć znaku char (2) z zestawem znaków latin1, aby zająć tylko minimalną ilość miejsca.
źródło
CHAR
. W przypadku InnoDB dzieje się tak wiele innych rzeczy, że debata „dynamiczny / stały rozmiar wiersza” jest zasadniczo nieistotna.CHAR
.Jeśli połączysz się z bazą danych przy użyciu kodowania latin1 (na przykład z PHP), aby zapisać ciąg PHP UTF8 w kolumnie MySQL UTF8, będziesz mieć podwójne kodowanie UTF8.
Jeśli łańcuch UTF8
$s
ma 32 znaki, ale 64 bajty, a kolumna maVARCHAR(32)
format UTF8, podwójne kodowanie spowoduje konwersję ciągu$s
na 64-znakowy ciąg UTF8, który zostanie obcięty w bazie danych do jego 32 pierwszych znaków odpowiadających 32 pierwszym bajtom z$s
. Możesz pomyśleć, że MySQL 5 zachowuje się jak MySQL 4, ale w rzeczywistości jest to druga przyczyna tego samego efektu.źródło