Всем привет. В этом видео мы продолжим разбирать типы данных MySQL и рассмотрим символьные типы данных и тип JSON. Символьные типы данных - это CHAR, VARCHAR, BINARY, VARBINARY, несколько видов BLOBа, несколько видов текста, ENUM и SET. Типы CHAR и VARCHAR очень похожи друг на друга, но хранятся по-разному. CHAR, в скобочках можно указать максимальное количество символов, - это строка фиксированной длины. Если вы сохраняете значение меньшей длины, чем указали при создании, то оно дополняется справа пробелами. При получении эти пробелы как бы отрезаются. При этом М - максимальная длина строки, может быть от 0 до 255 символов, и занимать в базе такая строка будет М*W байт, где W - это размер одного символа в кодировке. Если это кодировка типа windows1251 или latin1, то это один байт, в UTF-8 это три байта на символ, И UTF-8mb4 - четыре байта на символ. VARCHAR очень похож на CHAR, но это строка переменной длины. Она практически такая же, только не дополняется пробелами, то есть сохраняет ровно столько символов, сколько вы туда запишите. При этом указывается максимальная длина строки, и нельзя сохранить строку больше этого, а меньшую можно, и она не будет ничем дополнена. Занимает L+1 или L+2 байта, в зависимости от М, на самом деле, максимальной длины. Опять-таки количество байт, которые занимает строка, зависит от кодировки, и несмотря на то, что нет явного ограничения на количество символов в строке VARCHAR, есть ограничения на максимальное количество байт в одном ряду в MySQL, это 65535 байт, Причем это для всех колонок в ряду, поэтому это накладывает ограничения на суммарную длину всех колонок. Соответственно, если вы сохраняете в VARCHAR строку длиннее чем М - максимальная длина которую вы указали при создании, то строка либо обрезается, либо происходит ошибка, в зависимости от настроек MySQL. Также интересно, что сравнение в MySQL, сравнение строк, не учитывает концевые пробелы, и поэтому сравнение строки А-пробел-пробел со строкой просто А вернёт истину. Для работ со строками в MySQL есть ряд функций, это такие как функции конкатенации, выделение подстрок, поиск подстроки, строки и другие. Также есть типы BINARY и VARBINARY, они очень похожи на CHAR и VARCHAR, отличаются тем, что хранят не символы, а байты. То есть, это такие же как CHAR и VARCHAR, но для хранения последовательностей байт, а не строк символов. BINARY точно так же как и CHAR дополняется справа, но нулями, а не пробелами, и в отличии эти нули при извлечении не обрезаются. Это может породить сложности при сравнении, при сортировке, это надо иметь ввиду. Также существуют типы данных BLOB и TEXT. BLOB - это binary large object, предназначен для сохранения больших двоичных данных. Есть в четырех вариантах: TINYBLOB, BLOB, MEDIUMBLOB и LONGBLOB. Отличаются они, разумеется, максимально допустимым размером сохраняемых данных - от 2 в восьмой степени байт до 2 в тридцать второй степени байт. Также и с текстом. Есть TINYTEXT, TEXT, MEDUIMTEXT и LONGTEXT. Как вы понимаете, это тоже самое, но для сохранения больших текстовых данных. Поскольку данные в этих полях могут быть действительно большими, то несмотря на размер самого поля, который может сохранить много данных, у вас может не получиться их туда сохранить, потому что вы можете упереться в размер памяти, доступной на сервере, размер коммуникационных буферов этого сервера, то есть у вас может просто не получиться передать пакет с такими большими данными или прочитать его обратно. Поэтому с этими полями надо быть осторожным. То есть, все определяется не только размерами самих полей, но и какого-то окружения. Есть другие нюансы с такими большими полями. Например, при сортировке учитывается не все поле, а только первые несколько его символов, но определенные, на самом деле, настройками max_sort_length, настройками MySQL. Вот такие интересные поля. Также есть поле ENUM - перечисление. В этом поле при создании можно перечислить значения, которые в нем допускаются строковые, и по факту оно может содержать одно из этих значений. То есть, вы присваиваете колонке одно из этих значений, а внутри оно преобразуется в индекс этого значения и сохранится в базе в виде одного или двух байт, в зависимости от того, сколько всего значений есть в этом перечислении, сколько вы их указали при создании, если до 255, то это будет один байт, если больше, то 2 байта. Всего максимум можно указать 65535 значений. Соответственно, вы как бы записываете в это поле строку и обратно, когда вы прочитаете, прочтется строка, одно из значений возможных, допустимых, но внутри оно хранится как число, индекс этого значения внутри перечисления. Это порождает опять-таки интересные эффекты. Если вы начнете сортировать по этой колонке, то будет сортироваться она не по строковому представлению, а по индексу, по порядковому значению этого строкового представления внутри перечисления. Поэтому если вы сделаете ENUM, например (b;a;c), из трех значений b,a,c, именно им в таком порядке, то значение b у вас при сортировке окажется выше, чем значение а, и в свою очередь они все выше, чем значение с, ровно потому что не по символьному представлению, а по числовому индексу, по порядку внутри перечисления. И также лучше не делать никогда значениями ENUM цифры, потому что, когда вы сохраняете и передаете это значение ENUM в MySQL, вы можете передать как и его строковое представление, так, в принципе, и индекс. А когда у вас строковым представлением тоже является цифра, MySQL может перепутать, и вы можете получить не то, что сохраняли. Вот такой нюанс. Также есть тип данных SET - множество. Он похож на ENUM в том смысле, что это - набор значений строковых, но только может хранится ни одно из них, а несколько одновременно выбранных в каждой ячейке. По сути, каждое значение за ним закрепляется какой-то бит в последовательности битов и записываются номера битов этих значений, и получается одно число, тоже число, и оно сохраняется в базе данных. Соответственно, может занимать один два три четыре или восемь байт в зависимости от того, сколько всего разных значений вы перечислили при создании SETа. Максимум может быть 64 значения. Каждый элемент представлен каким-то своим битом. Давайте поговорим о типе данных JSON. Он не так давно появился в MySQL, хотя, в принципе, и до этого вы спокойно могли сохранять JSON, например, в поле с типом текст, никто вам не мешал. Потому что JSON - это, по сути, строка, но тип JSON всё-таки отличается от просто сохранения строки в текст, так как, если вы сохраните какую-то строку в JSON, то, во-первых, она будет проверена на соответствие формату перед тем, как попасть в базу данных. Т.е. если у вас быть невалидный JSON, база данных может выдать ошибку. Также поля типа JSON внутри хранятся в специальном компактном формате, который быстрее читается, и удобнее с ним работать базе данных. И к тому же для работы с полями типа JSON есть специальные функции, которые позволяют внутри поля добавлять какие-то элементы, удалять, в общем, манипулировать с подэлементами, находящимися внутри поля JSON. По полям типа JSON нельзя сделать индексы, по полям внутри JSONа, но можно сделать, на самом деле, автогенерируемые колонки, MySQL тоже такое позволяет делать, когда одни колонки генерируются на основе других колонок, значения этих колонок. И вот уже по автогенерируемым колонкам, которые будут генерироваться на основе каких-то полей изнутри JSON, можно сделать индексы, если вдруг вам захочется сделать индексы по полям внутри JSONа. Собственно, мы рассмотрели все типы данных, пропустили, правда, пространственные типы данных. Теперь мы знаем, какие вообще виды значений мы можем хранить в колонках MySQL, и можем выбрать нужные нам форматы колонок, возможно, конечно, подглядев в документацию. Важно помнить что - для ваших значений лучше выбрать не просто подходящий формат, а наименьший, наиболее компактный из подходящих. Если вам нужны числа от 0 до 255, то лучше выбрать UNSIGNED TINYINT, потому что он занимает меньше всего байт и способен хранить эти числа. Если нужны большие диапазоны, то выбирать какие-то другие. Ведь чем более компактный формат вы выберете, тем меньше у вас будет занимать каждый ряд в таблице. А если в таблице очень много рядов, миллионы, сотни миллионов записей, то каждый сэкономленный байт выльется в мегабайты и гигабайты, возможно, данных. Соответственно, это будет быстрее и меньше занимать места. В следующем видео мы научимся уже манипулировать данными, сохранять данные в таблице, извлекать и так далее.