Я сейчас работаю с базой данных SQL, и это всегда вызывало у меня любопытство, но поиски в Google мало что показывают: почему строгие типы данных?
Я понимаю, почему у вас есть несколько разных типов данных, например, например, насколько важно различать двоичные и простые текстовые данные . Вместо того, чтобы хранить 1 и 0 двоичных данных в виде открытого текста, я теперь понимаю, что более эффективно хранить двоичные данные в своем собственном формате.
Но я не понимаю, какая польза от такого большого количества разных типов данных:
- Почему
mediumtext
,longtext
иtext
? - Почему
decimal
,float
иint
? - и т.п.
В чем преимущество сообщения базы данных: «В этом столбце будет только 256 байтов данных в виде простого текста». или "Этот столбец может содержать текстовые записи длиной до 16 777 215 байт"?
Это выигрыш в производительности? Если так, то почему знание размера записи перед рукой помогает в производительности? Или скорее это что-то совсем другое?
источник
decimal
,float
иint
типов, то , что вы ожидали бы1 / 3
сделать? Как насчет1.0 / 3.0
? Можете ли вы быть уверены, что когда вы поделитесьcolumnA
наcolumnB
это, вы получите ожидаемые результаты?Ответы:
SQL является статически типизированным языком. Это означает, что вы должны знать, к какому типу относится переменная (или поле, в данном случае), прежде чем вы сможете ее использовать. Это противоположность динамически типизированных языков, где это не обязательно так.
По своей сути, SQL предназначен для определения данных ( DDL ) и доступа к данным ( DML ) в механизме реляционной базы данных . Статическая типизация предоставляет несколько преимуществ по сравнению с динамической типизацией для этого типа системы.
Индексы , используемые для быстрого доступа к определенным записям, работают очень хорошо, когда размер фиксирован. Рассмотрим запрос, использующий индекс, возможно, с несколькими полями: если типы и размеры данных известны заранее, я могу очень быстро сравнить мой предикат (предложение WHERE или критерии JOIN) со значениями в индексе и быстрее найти нужные записи ,
Рассмотрим два целочисленных значения. В динамической системе типов они могут иметь переменный размер (например, Java
BigInteger
или встроенные в Python целые числа произвольной точности). Если я хочу сравнить целые числа, мне нужно сначала узнать их длину в битах. Это аспект целочисленного сравнения, который в значительной степени скрыт современными языками, но очень реален на уровне процессора. Если размеры фиксированы и известны заранее, весь процесс удаляется из процесса. Опять же, предполагается, что базы данных смогут обрабатывать миллиарды транзакций как можно быстрее. Скорость - это король.SQL был разработан еще в 1970-х годах. В первые дни микрокомпьютинга память была на высоте. Ограничение данных помогло контролировать требования к хранилищу. Если целое число никогда не превышает одного байта, зачем выделять для него больше памяти? Это пустое пространство в эпоху ограниченной памяти. Даже в наше время эти лишние потраченные байты могут увеличивать и снижать производительность кэша ЦП. Помните, что это движки баз данных, которые могут обслуживать сотни транзакций в секунду, а не только вашу маленькую среду разработки.
В дополнение к ограниченному хранилищу полезно иметь возможность разместить одну запись на одной странице в памяти. Когда вы переходите на одну страницу, появляется больше пропусков страниц и более медленный доступ к памяти. У более новых движков есть оптимизация, чтобы сделать это менее серьезной проблемой, но она все еще там. Подбирая размер данных соответствующим образом, вы можете уменьшить этот риск.
Moreso в наше время, SQL используется для подключения к другим языкам через ORM или ODBC или какой - либо другой слой. В некоторых из этих языков есть правила о необходимости сильных статических типов. Лучше всего соответствовать более строгим требованиям, поскольку языки с динамической типизацией могут справляться со статическими типами легче, чем наоборот.
SQL поддерживает статическую типизацию, потому что движкам баз данных она нужна для производительности, как показано выше.
Интересно отметить, что существуют реализации SQL, которые не являются строго типизированными. SQLite , пожалуй, самый популярный пример такого механизма реляционных баз данных. С другой стороны, он предназначен для однопоточного использования в одной системе, поэтому проблемы с производительностью могут быть не такими явными, как, например, в случае корпоративной базы данных Oracle, обслуживающей миллионы запросов в минуту.
источник
Indexes
, в основном говорится: наличие типа данных позволяет ядру базы данных анализировать данные , проводить сравнения (большие / меньшие числа, более ранние / более поздние даты, до / после в алфавите), и, следовательно, позволяет сортировать и запрашивать .Во-первых: простой текст является двоичным (это даже не символы UTF8 или ASCII "0" и "1", а фактические биты включения / выключения)
Тем не менее, некоторые из причин:
источник
Это происходит из-за того, что базовый код, в котором написана база данных, может выделять и использовать записи фиксированного размера, если он знает, что конкретное поле может содержать от 0 до 256 символов текста, то он может выделить блок из 256 байтов для его хранения.
Это значительно ускоряет процесс, например, вам не нужно выделять дополнительное хранилище по мере ввода пользователем данных, поскольку данное поле всегда начинает x байтов в записи, которую поиск или выбор в этом поле знает, чтобы всегда проверять x байтов в каждой записи и т. Д.
источник
Когда столбцы базы данных имеют определенные типы, типы обычно определяются сами по себе, чтобы иметь определенный размер в битах. В результате:
1) когда движок базы данных перебирает строки в таблице, ему не нужно выполнять какой-либо сложный анализ, чтобы определить, где заканчивается каждая запись, он может просто знать, что каждая строка состоит, скажем, из 32 байтов, и, таким образом, чтобы получить Для следующей записи достаточно добавить 32 байта в текущее местоположение записи.
2) при поиске поля в строке можно снова узнать точное смещение для этого поля, ничего не анализируя, поэтому поиск по столбцам представляет собой простую арифметическую операцию, а не потенциально дорогостоящую обработку данных.
источник
Вы спросили, почему СУБД имеют статические типы данных.
Скорость поиска. Смысл СУБД в том, чтобы хранить гораздо больше данных, чем вы могли бы загрузить в программу. Подумайте: «Все слипы кредитных карт, сгенерированные в мире за последние десять лет». Для эффективного поиска таких данных полезны типы данных фиксированной длины. Это особенно верно для структурированных данных, таких как отметки даты и номера счетов. Если вы заранее знаете, с чем имеете дело, проще загрузить эффективные индексы.
Целостность и ограничения. Проще содержать данные в чистоте, если они имеют фиксированные типы данных.
История. СУБД начали работать, когда у компьютеров было всего несколько мегабайт оперативной памяти, а объем хранения в терабайтах был чрезвычайно дорогим. Сохранение дюжины байтов в каждом ряду таблицы может сэкономить тысячи долларов и часов времени при таких обстоятельствах.
Проклятие клиентской базы. СУБД сегодня являются очень сложными, высоко оптимизированными программными пакетами, и они используются для накопления данных в течение десятилетий. Они зрелые. Они работают. Сбой СУБД, приводящий к крупномасштабной потере данных, сегодня чрезвычайно редок. Переход на что-либо с более гибкой системой ввода данных не стоит затрат или риска для большинства организаций.
Аналогия: может быть слепо очевидно, что городские системы метрополитена будут работать лучше (тише, быстрее, энергоэффективнее) на узкой железнодорожной колею. Но как вы собираетесь изменить все рельсы в системе метро Нью-Йорка, чтобы реализовать эти улучшения? Нет, поэтому вы оптимизируете то, что имеете.
источник
В целом, чем больше вы сообщаете базе данных о том, что вы храните, тем больше она может пытаться оптимизировать различные показатели производительности, связанные с этими данными, например, сколько места на диске или сколько памяти выделяется при извлечении. ,
Не уверен, какую базу данных вы используете, поэтому мне придется угадать: я предполагаю, что два из этих типов данных имеют верхние пределы, один из них - нет. Использование типов данных для текста с верхним пределом сообщает базе данных, сколько места потребуется для каждой записи. Также возможно, что в некоторых базах данных могут быть разные способы хранения большого (возможно, неограниченного) текста по сравнению с небольшим текстом фиксированной длины (это может варьироваться в зависимости от базы данных, обратитесь к руководству, чтобы узнать о своем).
Различные уровни точности требуют разных объемов хранения, и не каждое использование требует высочайших степеней точности. Например, смотрите здесь: https://docs.oracle.com/cd/B28359_01/server.111/b28286/sql_elements001.htm#SQLRF50950
В Oracle имеется целый ряд различных числовых типов с различными требованиями к хранилищу и различными возможностями с точки зрения уровня точности и размера числа, которое может быть представлено.
источник
В какой-то степени это исторически.
Когда-то давно табличные данные хранились в файлах, состоящих из записей фиксированной длины, которые, в свою очередь, состояли из заранее определенных полей, так что данное поле всегда было одного типа и в одном и том же месте в каждой записи. Это сделало обработку эффективной и ограничило сложность кодирования.
Добавьте несколько индексов в такой файл, и у вас есть начало реляционной базы данных.
По мере развития реляционных баз данных они начали вводить больше типов данных и вариантов хранения, включая текстовые или двоичные поля переменной длины. Но это привело к появлению записей переменной длины и лишило возможности последовательно находить записи с помощью вычислений или полей с фиксированным смещением. Неважно, машины сегодня намного мощнее, чем тогда.
Иногда полезно установить определенный размер для поля, чтобы помочь реализовать некоторую часть бизнес-логики - скажем, 10 цифр для номера телефона в Северной Америке. В большинстве случаев это всего лишь немного компьютерного наследия.
источник
Если база данных использует записи фиксированного размера, любая запись в базе данных будет продолжать помещаться в том же месте, даже если ее содержимое будет изменено. Напротив, если база данных пытается хранить записи, используя именно тот объем памяти, который необходим для их полей, изменение имени Эммы Смит на Эмма Джонсон может привести к тому, что ее запись окажется слишком большой, чтобы поместиться в ее текущее местоположение. Если запись перемещается в какое-то место с достаточным пространством, любой индекс, который отслеживает, где она находится, необходимо обновить, чтобы отразить новое местоположение.
Существует множество способов снизить стоимость таких обновлений. Например, если система поддерживает список номеров записей и местоположений данных, этот список будет единственным, что необходимо будет обновить при перемещении записи. К сожалению, такие подходы все еще имеют значительную стоимость (например, для сохранения соответствия между номерами записей и местоположениями потребуется, чтобы поиск записей потребовал дополнительного шага для извлечения данных, связанных с данным номером записи). Использование записей фиксированного размера может показаться неэффективным, но это делает вещи намного проще.
источник
Для многих вещей, которые вы делаете в качестве веб-разработчика, нет необходимости понимать, что происходит «под капотом». Однако бывают случаи, когда это помогает.
Как вы подозреваете, причина в эффективности. Утечка абстракций . Подобный запрос
SELECT author FROM books
может выполняться довольно быстро, если известны размеры всех полей в таблице.Как говорит Джоэл,
Большую часть времени вы работаете достаточно далеко от мрачных оснований, которые вам не нужны. Как веб-разработчик на основе PHP, вы заботитесь о том, сколько инструкций процессора использует ваш код? В большинстве случаев нет, не совсем. Но иногда полезно знать по двум причинам: он может объяснить решения, принятые вашими библиотеками; и иногда вам нужно заботиться о скорости в вашем собственном коде.
источник