<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=91.143.51.202&amp;*</id>
		<title>Викиконспекты - Вклад участника [ru]</title>
		<link rel="self" type="application/atom+xml" href="http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=91.143.51.202&amp;*"/>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/91.143.51.202"/>
		<updated>2026-06-11T20:34:34Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D0%B0%D1%86%D0%B8%D1%8F_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85._%D0%A3%D0%BF%D0%BE%D1%80%D1%8F%D0%B4%D0%BE%D1%87%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5_%D0%B8_%D1%85%D0%B5%D1%88-%D0%B8%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D1%8B&amp;diff=82043</id>
		<title>Индексация данных. Упорядоченные и хеш-индексы</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D0%B0%D1%86%D0%B8%D1%8F_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85._%D0%A3%D0%BF%D0%BE%D1%80%D1%8F%D0%B4%D0%BE%D1%87%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5_%D0%B8_%D1%85%D0%B5%D1%88-%D0%B8%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D1%8B&amp;diff=82043"/>
				<updated>2021-12-27T10:12:55Z</updated>
		
		<summary type="html">&lt;p&gt;91.143.51.202: /* Упорядоченные индексы */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Индексы ==&lt;br /&gt;
&lt;br /&gt;
Индексы нужны для того, чтобы оптимально искать нужные записи в таблице.&lt;br /&gt;
&lt;br /&gt;
Всего есть два способа найти нужные данные:&lt;br /&gt;
* Полный просмотр таблицы&lt;br /&gt;
** Последовательный перебор записей&lt;br /&gt;
** Быстро работает на маленьких таблицах, но медленно на средних и больших&lt;br /&gt;
** Если выбираем большую часть данных, то работает быстро. Иначе - медленно&lt;br /&gt;
* Индекс&lt;br /&gt;
** Произвольный набор столбцов&lt;br /&gt;
** Требуется предварительная обработка таблицы как при построении, так и при обновлении&lt;br /&gt;
** Быстрый поиск в индексе, сразу получаем указатель на запись&lt;br /&gt;
&lt;br /&gt;
На больших данных вся таблица не помещяется в память, из-за этого время работы очень сильно возрастает. &lt;br /&gt;
&lt;br /&gt;
Из-за всего вышеперечисленного, на больших данных использование полного просмотра становится на практике неприемлимым и используется индексация. На маленьких данных полный перебор работает хорошо и создание дополнительных струкрур поверх данных не окупается, поэтому может применяться на практике. &lt;br /&gt;
&lt;br /&gt;
=== Кластеризованный индекс ===&lt;br /&gt;
&lt;br /&gt;
[[Файл:Index_Clustered.png|мини|Кластеризованный индекс]]&lt;br /&gt;
&lt;br /&gt;
Если данные в таблице хранятся в порядке индекса, то такой индекс называется '''кластеризованным'''. Кластеризованный индекс позволяет увеличить скорость просмотра, так как нет дополнительной операции загрузки данных, однако так хранить данные возможно только если в таблице есть всего один индекс.&lt;br /&gt;
&lt;br /&gt;
=== Структура Индекса ===&lt;br /&gt;
&lt;br /&gt;
[[Файл:Index_Structure.png|мини|Структура индекса]]&lt;br /&gt;
&lt;br /&gt;
В общем случае индексы хранят отображение из ключей на идентификаторы записей, которые ведут на записи, которые мы загружаем&lt;br /&gt;
&lt;br /&gt;
Есть два подхода к реализации индексов: &lt;br /&gt;
* Хеш-таблицы&lt;br /&gt;
* Деревья поиска&lt;br /&gt;
&lt;br /&gt;
== Хеш-индексы == &lt;br /&gt;
&lt;br /&gt;
Хеш-функция задается разработчиком СУБД а не пользователем, чаще всего это эффективно вычисляемые хеш-функции, которые имеют гарантии статистического распределения. Атаки возможны, однако хеш-функцию легко поменять, поэтому атаки ненадежны.&lt;br /&gt;
&lt;br /&gt;
* Предварительная обработка &lt;br /&gt;
** Подсчет хешей ключей.&lt;br /&gt;
** Разбиение на корзины&lt;br /&gt;
* Поиск в индексе&lt;br /&gt;
** Просмотр корзины&lt;br /&gt;
** Несколько ключей в корзине. Коллизии могут быть, так как индекс не всегда ключ, поэтому нормально если есть повторяющиеся начения. Хеш-таблица все еще честная, но она должна понимать, что значения могут дублироваться.&lt;br /&gt;
** Если хеш-индекс является надключем, то СУБД может этим воспользоваться и гарантировать, что дублирующихся значений не будет.&lt;br /&gt;
* Заголовок помещяется в памяти&lt;br /&gt;
[[Файл:Index_Hash_Simple.png|мини|Простой хеш-индекс]]&lt;br /&gt;
&lt;br /&gt;
Однако может наступить момент, когда очередная корзина не помещается в страницу, в таком случае мы так же храним их цепочками. &lt;br /&gt;
&lt;br /&gt;
* Так как хеш-функция хорошая, то в цепочке только полезные данные&lt;br /&gt;
* Если цепочка длинная, значит этому набору столбцов соответствует много строк, значит база данных так и задумывалась.&lt;br /&gt;
&lt;br /&gt;
При этом получаем линейное время поиска&lt;br /&gt;
Но в случае если данных много, мы не можем просто увеличить число корзин и перенести данные, так как перехешировать таблицу очень долго&lt;br /&gt;
&lt;br /&gt;
[[Файл:Index_Hash_Sequence.png|мини|Цепочки страниц]]&lt;br /&gt;
&lt;br /&gt;
=== Расширяемое хеширование ===&lt;br /&gt;
&lt;br /&gt;
Изначально создаем большое количество корзин, сильно больше чем требуется. Пока мало данных Храним несколько корзин на одной странице, чтобы не аллоцировать для каждой корзины по отдельной странице.&lt;br /&gt;
* Обычно выбираем набор корзин, которые идут подряд&lt;br /&gt;
* При переполнении страницы разделенем корзины на две страницы&lt;br /&gt;
* Не работает при плохой хеш-функции, но у нас хорошая&lt;br /&gt;
&lt;br /&gt;
При переполнении страницы мы:&lt;br /&gt;
* разделяем ее на несколько страниц&lt;br /&gt;
* разделим страницы, которые на нее ссылались, на несколько групп&lt;br /&gt;
Стоимость: $1$ чтение и запись стольких страниц, на сколько мы разделили (обычно $2$)&lt;br /&gt;
* Каждой такой группе выделим по странице&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:Index_Hash_Extendable.png|мини|Расширяемое хеширование]]&lt;br /&gt;
&lt;br /&gt;
=== Побитное расширяемое хеширование ===&lt;br /&gt;
Заранее сделаем заголовок большого размера. &lt;br /&gt;
* Глубина хеша $n$ - создаем корзины для $n$ бит нашего хеша&lt;br /&gt;
** Получаем $2^n$ корзин&lt;br /&gt;
* Для каждой страницы хранится ее локальная глубина $k$, это значит что она хранит $2^{n−k}$ последовательных корзин на странице. При этом локальная глубина может быть разной для разных страниц&lt;br /&gt;
* При переполнении происходит разделение корзин. Страница глубины $k$ разделяется на две глубины $k+1$&lt;br /&gt;
&lt;br /&gt;
Есть точные гарантии по производительности~--- все наши затраты измеряются единицами страниц.&lt;br /&gt;
&lt;br /&gt;
=== Ускоряемые запросы ===&lt;br /&gt;
&lt;br /&gt;
*Проверка существования ключа&lt;br /&gt;
**Проверка повторений (ключи) &lt;br /&gt;
**''in'' - только если есть все необходимые атрибуты, то есть даны все столбцы, которые есть в хеш-индексе. Иначе индек не поможет, так как нет способа перебрать все варианты&lt;br /&gt;
**''exist'' - только если есть все необходимые атрибуты, анологично с ''in''&lt;br /&gt;
**''count'' - при запросе ''count*'' зачастую можно посчитать по индексу количество записей с определенным набором стобцов, не обращаясь к самим записям, что дает существенный выигрыш по премени&lt;br /&gt;
*Поиск по ключу&lt;br /&gt;
**Естественные соединения. Если есть идентификатор, по этому идентификатору есть хеш-индекс, это, в свою очередь, позволяет быстро найти запись.&lt;br /&gt;
&lt;br /&gt;
== Упорядоченные индексы ==&lt;br /&gt;
&lt;br /&gt;
Традиционно реализуются на деревьях поиска&lt;br /&gt;
&lt;br /&gt;
* Предварительная обработка&lt;br /&gt;
** Ключи упорядочиваются по возрастанию - так как ключ составной, то используем лексикографисечкое упорядочивание, после упорядочиваем по возрастанию и строим поверх этого дерево поиска&lt;br /&gt;
* Поиск в индексе&lt;br /&gt;
** Ищем данные в дереве поиска. Используемое дерево поиска должно поддерживать операции вставки, удаления и поиска&lt;br /&gt;
&lt;br /&gt;
Деревья поиска&lt;br /&gt;
* Количество операций обычно пропорционально $O$(высоты). Так как время выполнение операций зависит от высоты дерева, для оптимизации времени нужно минимизировать высоту&lt;br /&gt;
* Размер узла&lt;br /&gt;
** Хотим эффективно использовать страницы&lt;br /&gt;
** Используем сильно ветвящиеся деревья. Так размер узла будет примерно равен странице и высота дерева будет минимальной&lt;br /&gt;
&lt;br /&gt;
=== $B$ и $B+$ деревья ===&lt;br /&gt;
&lt;br /&gt;
Обычно в качестве сильно ветвящихся деревьев поиска берут $B$ и $B+$ деревья и их разновидности.&lt;br /&gt;
&lt;br /&gt;
* $B$ деревья степени $n$&lt;br /&gt;
** В каждом узле от $\frac{n}{2}$ до n детей&lt;br /&gt;
** Указатели и ключи хранятся в узлах&lt;br /&gt;
* $B+$ деревья степени $n$&lt;br /&gt;
** От $\frac{n}{2}$ до $n$ детей&lt;br /&gt;
** Указатели хранятся в листьях&lt;br /&gt;
&lt;br /&gt;
* $B+$ меньше данных в узлах - сильнее ветвятся&lt;br /&gt;
* $B+$ на одну страницу глубже, а это значит что больше образений к листу.&lt;br /&gt;
&lt;br /&gt;
Мы храним корень и несколько первых уровней в памяти для быстрого обращения, из-за этого время работы может резко возрастать, когда заканчивается закешированные уровни. Поэтому даже один лишний уровень в дереве может значительно увеличить время исполнения&lt;br /&gt;
&lt;br /&gt;
=== Плотные и разряженные индексы ===&lt;br /&gt;
Индексы также делятся на плотные и разряженные &lt;br /&gt;
* Плотный индекс. Храним ключи всех элементов подряд&lt;br /&gt;
* Разряженные индекс. Храним ключи части элементов &lt;br /&gt;
** Обычно – один на страницу, мы можем найти данные в рамках этой страницы без загрузки новых. Разряженный индекс бычно используется для кластеризованных индексов&lt;br /&gt;
** Уменьшает число уровней так как храним меньше индексов. Вспоминая что даже один уровень может повысить количество загрузок в два раза, понимаем что разряженные индексы могут сильно оптимизировать базу данных&lt;br /&gt;
&lt;br /&gt;
Так как упорядоченный индекс хранит сами данные в узлах, а не только хеш, то чем больше индексируеммые данные, тем меньше степень ветвления, тем больше высота дерева.&lt;br /&gt;
Поэтому в упорядоченных индексах, в отличии от хеш-индексов, нужно обращать внимание на то, что является индексом:&lt;br /&gt;
&lt;br /&gt;
*Строки - часто бывают большие, нужно очень аккуратно&lt;br /&gt;
**Если есть последовательно упорядоченные строки, то можно использовать префиксы, сильно оптимизируя размер индекса&lt;br /&gt;
*Суррогатные ключи. Обычно имеют малый размер, поэтому получается низкое и широкое дерево поиска, что нам и нужно&lt;br /&gt;
*Изменяющиеся данные. При изменении данных нужно перестраивать дерево, это не эффективно&lt;br /&gt;
**Индексы часто не умеют уменьшаться~--- удаление данных не приводит к уменьшению дерева. Подразумевается, что запускается отдельная программа, которая перестраивает индексы&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ускоряемые запросы ===&lt;br /&gt;
* Проверка существования ключа&lt;br /&gt;
* Поиск по ключу&lt;br /&gt;
* Минимум и максимум среди значений, на которых построен ключ, в хеш-таблицах этого нет&lt;br /&gt;
* Можно реализовать поиск в диапазоне&lt;br /&gt;
** В хеш-индексах единственный способ - перебрать всю таблицу, поэтому обчно так не делают. А в упорядоченных нет с этим проблем, если все необходимые столбцы входят в ключ&lt;br /&gt;
** ''count''. count * работает быстрее, так как не нужно идти по всем данным&lt;br /&gt;
* Если построен на строках, ''like'', но только по префиксу&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;br /&gt;
* ''Дейт К. Введение в системы баз данных (Приложение Г)''&lt;br /&gt;
* ''Кнут Д. Искусство программирования. Том 3. Сортировка и поиск''&lt;br /&gt;
* ''Silberschatz A., Korth H. F., Sudarshan S. Database System Concepts''&lt;br /&gt;
&lt;br /&gt;
[[Категория: Базы данных]]&lt;/div&gt;</summary>
		<author><name>91.143.51.202</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D0%B0%D1%86%D0%B8%D1%8F_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85._%D0%A3%D0%BF%D0%BE%D1%80%D1%8F%D0%B4%D0%BE%D1%87%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5_%D0%B8_%D1%85%D0%B5%D1%88-%D0%B8%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D1%8B&amp;diff=82039</id>
		<title>Индексация данных. Упорядоченные и хеш-индексы</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D0%B0%D1%86%D0%B8%D1%8F_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85._%D0%A3%D0%BF%D0%BE%D1%80%D1%8F%D0%B4%D0%BE%D1%87%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5_%D0%B8_%D1%85%D0%B5%D1%88-%D0%B8%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D1%8B&amp;diff=82039"/>
				<updated>2021-12-27T09:52:27Z</updated>
		
		<summary type="html">&lt;p&gt;91.143.51.202: /* Ускоряемые запросы */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Индексы ==&lt;br /&gt;
&lt;br /&gt;
Индексы нужны для того, чтобы оптимально искать нужные записи в таблице.&lt;br /&gt;
&lt;br /&gt;
Всего есть два способа найти нужные данные:&lt;br /&gt;
* Полный просмотр таблицы&lt;br /&gt;
** Последовательный перебор записей&lt;br /&gt;
** Быстро работает на маленьких таблицах, но медленно на средних и больших&lt;br /&gt;
** Если выбираем большую часть данных, то работает быстро. Иначе - медленно&lt;br /&gt;
* Индекс&lt;br /&gt;
** Произвольный набор столбцов&lt;br /&gt;
** Требуется предварительная обработка таблицы как при построении, так и при обновлении&lt;br /&gt;
** Быстрый поиск в индексе, сразу получаем указатель на запись&lt;br /&gt;
&lt;br /&gt;
На больших данных вся таблица не помещяется в память, из-за этого время работы очень сильно возрастает. &lt;br /&gt;
&lt;br /&gt;
Из-за всего вышеперечисленного, на больших данных использование полного просмотра становится на практике неприемлимым и используется индексация. На маленьких данных полный перебор работает хорошо и создание дополнительных струкрур поверх данных не окупается, поэтому может применяться на практике. &lt;br /&gt;
&lt;br /&gt;
=== Кластеризованный индекс ===&lt;br /&gt;
&lt;br /&gt;
[[Файл:Index_Clustered.png|мини|Кластеризованный индекс]]&lt;br /&gt;
&lt;br /&gt;
Если данные в таблице хранятся в порядке индекса, то такой индекс называется '''кластеризованным'''. Кластеризованный индекс позволяет увеличить скорость просмотра, так как нет дополнительной операции загрузки данных, однако так хранить данные возможно только если в таблице есть всего один индекс.&lt;br /&gt;
&lt;br /&gt;
=== Структура Индекса ===&lt;br /&gt;
&lt;br /&gt;
[[Файл:Index_Structure.png|мини|Структура индекса]]&lt;br /&gt;
&lt;br /&gt;
В общем случае индексы хранят отображение из ключей на идентификаторы записей, которые ведут на записи, которые мы загружаем&lt;br /&gt;
&lt;br /&gt;
Есть два подхода к реализации индексов: &lt;br /&gt;
* Хеш-таблицы&lt;br /&gt;
* Деревья поиска&lt;br /&gt;
&lt;br /&gt;
== Хеш-индексы == &lt;br /&gt;
&lt;br /&gt;
Хеш-функция задается разработчиком СУБД а не пользователем, чаще всего это эффективно вычисляемые хеш-функции, которые имеют гарантии статистического распределения. Атаки возможны, однако хеш-функцию легко поменять, поэтому атаки ненадежны.&lt;br /&gt;
&lt;br /&gt;
* Предварительная обработка &lt;br /&gt;
** Подсчет хешей ключей.&lt;br /&gt;
** Разбиение на корзины&lt;br /&gt;
* Поиск в индексе&lt;br /&gt;
** Просмотр корзины&lt;br /&gt;
** Несколько ключей в корзине. Коллизии могут быть, так как индекс не всегда ключ, поэтому нормально если есть повторяющиеся начения. Хеш-таблица все еще честная, но она должна понимать, что значения могут дублироваться.&lt;br /&gt;
** Если хеш-индекс является надключем, то СУБД может этим воспользоваться и гарантировать, что дублирующихся значений не будет.&lt;br /&gt;
* Заголовок помещяется в памяти&lt;br /&gt;
[[Файл:Index_Hash_Simple.png|мини|Простой хеш-индекс]]&lt;br /&gt;
&lt;br /&gt;
Однако может наступить момент, когда очередная корзина не помещается в страницу, в таком случае мы так же храним их цепочками. &lt;br /&gt;
&lt;br /&gt;
* Так как хеш-функция хорошая, то в цепочке только полезные данные&lt;br /&gt;
* Если цепочка длинная, значит этому набору столбцов соответствует много строк, значит база данных так и задумывалась.&lt;br /&gt;
&lt;br /&gt;
При этом получаем линейное время поиска&lt;br /&gt;
Но в случае если данных много, мы не можем просто увеличить число корзин и перенести данные, так как перехешировать таблицу очень долго&lt;br /&gt;
&lt;br /&gt;
[[Файл:Index_Hash_Sequence.png|мини|Цепочки страниц]]&lt;br /&gt;
&lt;br /&gt;
=== Расширяемое хеширование ===&lt;br /&gt;
&lt;br /&gt;
Изначально создаем большое количество корзин, сильно больше чем требуется. Пока мало данных Храним несколько корзин на одной странице, чтобы не аллоцировать для каждой корзины по отдельной странице.&lt;br /&gt;
* Обычно выбираем набор корзин, которые идут подряд&lt;br /&gt;
* При переполнении страницы разделенем корзины на две страницы&lt;br /&gt;
* Не работает при плохой хеш-функции, но у нас хорошая&lt;br /&gt;
&lt;br /&gt;
При переполнении страницы мы:&lt;br /&gt;
* разделяем ее на несколько страниц&lt;br /&gt;
* разделим страницы, которые на нее ссылались, на несколько групп&lt;br /&gt;
Стоимость: $1$ чтение и запись стольких страниц, на сколько мы разделили (обычно $2$)&lt;br /&gt;
* Каждой такой группе выделим по странице&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:Index_Hash_Extendable.png|мини|Расширяемое хеширование]]&lt;br /&gt;
&lt;br /&gt;
=== Побитное расширяемое хеширование ===&lt;br /&gt;
Заранее сделаем заголовок большого размера. &lt;br /&gt;
* Глубина хеша $n$ - создаем корзины для $n$ бит нашего хеша&lt;br /&gt;
** Получаем $2^n$ корзин&lt;br /&gt;
* Для каждой страницы хранится ее локальная глубина $k$, это значит что она хранит $2^{n−k}$ последовательных корзин на странице. При этом локальная глубина может быть разной для разных страниц&lt;br /&gt;
* При переполнении происходит разделение корзин. Страница глубины $k$ разделяется на две глубины $k+1$&lt;br /&gt;
&lt;br /&gt;
Есть точные гарантии по производительности~--- все наши затраты измеряются единицами страниц.&lt;br /&gt;
&lt;br /&gt;
=== Ускоряемые запросы ===&lt;br /&gt;
&lt;br /&gt;
*Проверка существования ключа&lt;br /&gt;
**Проверка повторений (ключи) &lt;br /&gt;
**''in'' - только если есть все необходимые атрибуты, то есть даны все столбцы, которые есть в хеш-индексе. Иначе индек не поможет, так как нет способа перебрать все варианты&lt;br /&gt;
**''exist'' - только если есть все необходимые атрибуты, анологично с ''in''&lt;br /&gt;
**''count'' - при запросе ''count*'' зачастую можно посчитать по индексу количество записей с определенным набором стобцов, не обращаясь к самим записям, что дает существенный выигрыш по премени&lt;br /&gt;
*Поиск по ключу&lt;br /&gt;
**Естественные соединения. Если есть идентификатор, по этому идентификатору есть хеш-индекс, это, в свою очередь, позволяет быстро найти запись.&lt;br /&gt;
&lt;br /&gt;
== Упорядоченные индексы ==&lt;br /&gt;
&lt;br /&gt;
Традиционно реализуются на деревьях поиска&lt;br /&gt;
&lt;br /&gt;
* Предварительная обработка&lt;br /&gt;
** Ключи упорядочиваются по возрастанию - так как ключ составной, то используем лексикографисечкое возрастание&lt;br /&gt;
* Поиск в индексе&lt;br /&gt;
** Поиск в упорядоченной последовательности&lt;br /&gt;
&lt;br /&gt;
Деревья поиска&lt;br /&gt;
* Количество операций&lt;br /&gt;
** Обычно пропорционально $O$(высоты)&lt;br /&gt;
** Так как время выполнение операций зависит от высоты, для оптимизации времени нужно минимизировать высоту&lt;br /&gt;
* Размер узла&lt;br /&gt;
** Хотим эффективно использовать страницы&lt;br /&gt;
** Сильно ветвящиеся деревья, так размер узла будет ~странице и высота будет минимальной&lt;br /&gt;
&lt;br /&gt;
=== $B$ и $B+$ деревья ===&lt;br /&gt;
&lt;br /&gt;
* $B$ деревья степени $n$&lt;br /&gt;
** От $\frac{n}{2}$ до n детей&lt;br /&gt;
** Указатели и ключи хранятся в узлах&lt;br /&gt;
* $B+$ деревья степени $n$&lt;br /&gt;
** От $\frac{n}{2}$ до $n$ детей&lt;br /&gt;
** Указатели хранятся в листьях&lt;br /&gt;
&lt;br /&gt;
* $B+$ меньше данных в узлах - сильнее ветвятся&lt;br /&gt;
* $B+$ на одну страницу глубже&lt;br /&gt;
&lt;br /&gt;
Мы храним корень и несколько первых уровней в памяти для быстрого обращения, из-за этого время работы может резко возрастать, когда заканчивается закешированные уровни.&lt;br /&gt;
&lt;br /&gt;
=== Плотные и разряженные индексы ===&lt;br /&gt;
&lt;br /&gt;
* Плотный индекс&lt;br /&gt;
** Храним ключи всех элементов&lt;br /&gt;
* Разряженные индекс&lt;br /&gt;
** Храним ключи части элементов&lt;br /&gt;
** Обычно – один на страницу, мы можем найти данные в рамках этой страницы без загрузки новых&lt;br /&gt;
** Разряженный индекс бычно используется для кластеризованных индексов&lt;br /&gt;
** Уменьшает число уровней&lt;br /&gt;
&lt;br /&gt;
Так как упорядоченных индекс хранит сами данные в узлах, а не только хеш, то чем больше индексируеммые данные, тем меньше степень ветвления&lt;br /&gt;
&lt;br /&gt;
*Строки&lt;br /&gt;
**Много данных в ключе – меньше степень ветвления&lt;br /&gt;
**Можно использовать префиксы&lt;br /&gt;
**Строки опасно использовать в качестве индекса, может сильно вырости высота дерева&lt;br /&gt;
*Суррогатные ключи&lt;br /&gt;
**Малый размер&lt;br /&gt;
**Выше эффективность&lt;br /&gt;
**Широкие и низкие деревья - хорошо&lt;br /&gt;
*Изменяющиеся данные&lt;br /&gt;
**Частое обновление индекса&lt;br /&gt;
**Уменьшение индекса&lt;br /&gt;
**Не эффективно, для уменьшения данных нужна отдельная таска&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ускоряемые запросы ===&lt;br /&gt;
* Проверка существования ключа&lt;br /&gt;
* Поиск по ключу&lt;br /&gt;
* Минимум и максимум среди значений, на которых построен ключ&lt;br /&gt;
* Диапазон &lt;br /&gt;
** Загрузка&lt;br /&gt;
** count. count * работает быстроее, так как не нужно идти по всем данным&lt;br /&gt;
* Если построен на строках, like по префиксу&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;br /&gt;
* ''Дейт К. Введение в системы баз данных (Приложение Г)''&lt;br /&gt;
* ''Кнут Д. Искусство программирования. Том 3. Сортировка и поиск''&lt;br /&gt;
* ''Silberschatz A., Korth H. F., Sudarshan S. Database System Concepts''&lt;br /&gt;
&lt;br /&gt;
[[Категория: Базы данных]]&lt;/div&gt;</summary>
		<author><name>91.143.51.202</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D0%B0%D1%86%D0%B8%D1%8F_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85._%D0%A3%D0%BF%D0%BE%D1%80%D1%8F%D0%B4%D0%BE%D1%87%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5_%D0%B8_%D1%85%D0%B5%D1%88-%D0%B8%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D1%8B&amp;diff=82037</id>
		<title>Индексация данных. Упорядоченные и хеш-индексы</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D0%B0%D1%86%D0%B8%D1%8F_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85._%D0%A3%D0%BF%D0%BE%D1%80%D1%8F%D0%B4%D0%BE%D1%87%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5_%D0%B8_%D1%85%D0%B5%D1%88-%D0%B8%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D1%8B&amp;diff=82037"/>
				<updated>2021-12-27T09:46:59Z</updated>
		
		<summary type="html">&lt;p&gt;91.143.51.202: /* Побитное расширяемое хеширование */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Индексы ==&lt;br /&gt;
&lt;br /&gt;
Индексы нужны для того, чтобы оптимально искать нужные записи в таблице.&lt;br /&gt;
&lt;br /&gt;
Всего есть два способа найти нужные данные:&lt;br /&gt;
* Полный просмотр таблицы&lt;br /&gt;
** Последовательный перебор записей&lt;br /&gt;
** Быстро работает на маленьких таблицах, но медленно на средних и больших&lt;br /&gt;
** Если выбираем большую часть данных, то работает быстро. Иначе - медленно&lt;br /&gt;
* Индекс&lt;br /&gt;
** Произвольный набор столбцов&lt;br /&gt;
** Требуется предварительная обработка таблицы как при построении, так и при обновлении&lt;br /&gt;
** Быстрый поиск в индексе, сразу получаем указатель на запись&lt;br /&gt;
&lt;br /&gt;
На больших данных вся таблица не помещяется в память, из-за этого время работы очень сильно возрастает. &lt;br /&gt;
&lt;br /&gt;
Из-за всего вышеперечисленного, на больших данных использование полного просмотра становится на практике неприемлимым и используется индексация. На маленьких данных полный перебор работает хорошо и создание дополнительных струкрур поверх данных не окупается, поэтому может применяться на практике. &lt;br /&gt;
&lt;br /&gt;
=== Кластеризованный индекс ===&lt;br /&gt;
&lt;br /&gt;
[[Файл:Index_Clustered.png|мини|Кластеризованный индекс]]&lt;br /&gt;
&lt;br /&gt;
Если данные в таблице хранятся в порядке индекса, то такой индекс называется '''кластеризованным'''. Кластеризованный индекс позволяет увеличить скорость просмотра, так как нет дополнительной операции загрузки данных, однако так хранить данные возможно только если в таблице есть всего один индекс.&lt;br /&gt;
&lt;br /&gt;
=== Структура Индекса ===&lt;br /&gt;
&lt;br /&gt;
[[Файл:Index_Structure.png|мини|Структура индекса]]&lt;br /&gt;
&lt;br /&gt;
В общем случае индексы хранят отображение из ключей на идентификаторы записей, которые ведут на записи, которые мы загружаем&lt;br /&gt;
&lt;br /&gt;
Есть два подхода к реализации индексов: &lt;br /&gt;
* Хеш-таблицы&lt;br /&gt;
* Деревья поиска&lt;br /&gt;
&lt;br /&gt;
== Хеш-индексы == &lt;br /&gt;
&lt;br /&gt;
Хеш-функция задается разработчиком СУБД а не пользователем, чаще всего это эффективно вычисляемые хеш-функции, которые имеют гарантии статистического распределения. Атаки возможны, однако хеш-функцию легко поменять, поэтому атаки ненадежны.&lt;br /&gt;
&lt;br /&gt;
* Предварительная обработка &lt;br /&gt;
** Подсчет хешей ключей.&lt;br /&gt;
** Разбиение на корзины&lt;br /&gt;
* Поиск в индексе&lt;br /&gt;
** Просмотр корзины&lt;br /&gt;
** Несколько ключей в корзине. Коллизии могут быть, так как индекс не всегда ключ, поэтому нормально если есть повторяющиеся начения. Хеш-таблица все еще честная, но она должна понимать, что значения могут дублироваться.&lt;br /&gt;
** Если хеш-индекс является надключем, то СУБД может этим воспользоваться и гарантировать, что дублирующихся значений не будет.&lt;br /&gt;
* Заголовок помещяется в памяти&lt;br /&gt;
[[Файл:Index_Hash_Simple.png|мини|Простой хеш-индекс]]&lt;br /&gt;
&lt;br /&gt;
Однако может наступить момент, когда очередная корзина не помещается в страницу, в таком случае мы так же храним их цепочками. &lt;br /&gt;
&lt;br /&gt;
* Так как хеш-функция хорошая, то в цепочке только полезные данные&lt;br /&gt;
* Если цепочка длинная, значит этому набору столбцов соответствует много строк, значит база данных так и задумывалась.&lt;br /&gt;
&lt;br /&gt;
При этом получаем линейное время поиска&lt;br /&gt;
Но в случае если данных много, мы не можем просто увеличить число корзин и перенести данные, так как перехешировать таблицу очень долго&lt;br /&gt;
&lt;br /&gt;
[[Файл:Index_Hash_Sequence.png|мини|Цепочки страниц]]&lt;br /&gt;
&lt;br /&gt;
=== Расширяемое хеширование ===&lt;br /&gt;
&lt;br /&gt;
Изначально создаем большое количество корзин, сильно больше чем требуется. Пока мало данных Храним несколько корзин на одной странице, чтобы не аллоцировать для каждой корзины по отдельной странице.&lt;br /&gt;
* Обычно выбираем набор корзин, которые идут подряд&lt;br /&gt;
* При переполнении страницы разделенем корзины на две страницы&lt;br /&gt;
* Не работает при плохой хеш-функции, но у нас хорошая&lt;br /&gt;
&lt;br /&gt;
При переполнении страницы мы:&lt;br /&gt;
* разделяем ее на несколько страниц&lt;br /&gt;
* разделим страницы, которые на нее ссылались, на несколько групп&lt;br /&gt;
Стоимость: $1$ чтение и запись стольких страниц, на сколько мы разделили (обычно $2$)&lt;br /&gt;
* Каждой такой группе выделим по странице&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:Index_Hash_Extendable.png|мини|Расширяемое хеширование]]&lt;br /&gt;
&lt;br /&gt;
=== Побитное расширяемое хеширование ===&lt;br /&gt;
Заранее сделаем заголовок большого размера. &lt;br /&gt;
* Глубина хеша $n$ - создаем корзины для $n$ бит нашего хеша&lt;br /&gt;
** Получаем $2^n$ корзин&lt;br /&gt;
* Для каждой страницы хранится ее локальная глубина $k$, это значит что она хранит $2^{n−k}$ последовательных корзин на странице. При этом локальная глубина может быть разной для разных страниц&lt;br /&gt;
* При переполнении происходит разделение корзин. Страница глубины $k$ разделяется на две глубины $k+1$&lt;br /&gt;
&lt;br /&gt;
Есть точные гарантии по производительности~--- все наши затраты измеряются единицами страниц.&lt;br /&gt;
&lt;br /&gt;
=== Ускоряемые запросы ===&lt;br /&gt;
&lt;br /&gt;
*Проверка существования ключа&lt;br /&gt;
**Проверка повторений (ключи)&lt;br /&gt;
**''in'' - только если есть все необходимые атрибуты&lt;br /&gt;
**''exist'' - только если есть все необходимые атрибуты&lt;br /&gt;
**''count'' - зачастую можно посчитать по индексу count, не обращаясь к самим записям&lt;br /&gt;
*Поиск по ключу&lt;br /&gt;
**Естественные соединения&lt;br /&gt;
&lt;br /&gt;
== Упорядоченные индексы ==&lt;br /&gt;
&lt;br /&gt;
Традиционно реализуются на деревьях поиска&lt;br /&gt;
&lt;br /&gt;
* Предварительная обработка&lt;br /&gt;
** Ключи упорядочиваются по возрастанию - так как ключ составной, то используем лексикографисечкое возрастание&lt;br /&gt;
* Поиск в индексе&lt;br /&gt;
** Поиск в упорядоченной последовательности&lt;br /&gt;
&lt;br /&gt;
Деревья поиска&lt;br /&gt;
* Количество операций&lt;br /&gt;
** Обычно пропорционально $O$(высоты)&lt;br /&gt;
** Так как время выполнение операций зависит от высоты, для оптимизации времени нужно минимизировать высоту&lt;br /&gt;
* Размер узла&lt;br /&gt;
** Хотим эффективно использовать страницы&lt;br /&gt;
** Сильно ветвящиеся деревья, так размер узла будет ~странице и высота будет минимальной&lt;br /&gt;
&lt;br /&gt;
=== $B$ и $B+$ деревья ===&lt;br /&gt;
&lt;br /&gt;
* $B$ деревья степени $n$&lt;br /&gt;
** От $\frac{n}{2}$ до n детей&lt;br /&gt;
** Указатели и ключи хранятся в узлах&lt;br /&gt;
* $B+$ деревья степени $n$&lt;br /&gt;
** От $\frac{n}{2}$ до $n$ детей&lt;br /&gt;
** Указатели хранятся в листьях&lt;br /&gt;
&lt;br /&gt;
* $B+$ меньше данных в узлах - сильнее ветвятся&lt;br /&gt;
* $B+$ на одну страницу глубже&lt;br /&gt;
&lt;br /&gt;
Мы храним корень и несколько первых уровней в памяти для быстрого обращения, из-за этого время работы может резко возрастать, когда заканчивается закешированные уровни.&lt;br /&gt;
&lt;br /&gt;
=== Плотные и разряженные индексы ===&lt;br /&gt;
&lt;br /&gt;
* Плотный индекс&lt;br /&gt;
** Храним ключи всех элементов&lt;br /&gt;
* Разряженные индекс&lt;br /&gt;
** Храним ключи части элементов&lt;br /&gt;
** Обычно – один на страницу, мы можем найти данные в рамках этой страницы без загрузки новых&lt;br /&gt;
** Разряженный индекс бычно используется для кластеризованных индексов&lt;br /&gt;
** Уменьшает число уровней&lt;br /&gt;
&lt;br /&gt;
Так как упорядоченных индекс хранит сами данные в узлах, а не только хеш, то чем больше индексируеммые данные, тем меньше степень ветвления&lt;br /&gt;
&lt;br /&gt;
*Строки&lt;br /&gt;
**Много данных в ключе – меньше степень ветвления&lt;br /&gt;
**Можно использовать префиксы&lt;br /&gt;
**Строки опасно использовать в качестве индекса, может сильно вырости высота дерева&lt;br /&gt;
*Суррогатные ключи&lt;br /&gt;
**Малый размер&lt;br /&gt;
**Выше эффективность&lt;br /&gt;
**Широкие и низкие деревья - хорошо&lt;br /&gt;
*Изменяющиеся данные&lt;br /&gt;
**Частое обновление индекса&lt;br /&gt;
**Уменьшение индекса&lt;br /&gt;
**Не эффективно, для уменьшения данных нужна отдельная таска&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ускоряемые запросы ===&lt;br /&gt;
* Проверка существования ключа&lt;br /&gt;
* Поиск по ключу&lt;br /&gt;
* Минимум и максимум среди значений, на которых построен ключ&lt;br /&gt;
* Диапазон &lt;br /&gt;
** Загрузка&lt;br /&gt;
** count. count * работает быстроее, так как не нужно идти по всем данным&lt;br /&gt;
* Если построен на строках, like по префиксу&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;br /&gt;
* ''Дейт К. Введение в системы баз данных (Приложение Г)''&lt;br /&gt;
* ''Кнут Д. Искусство программирования. Том 3. Сортировка и поиск''&lt;br /&gt;
* ''Silberschatz A., Korth H. F., Sudarshan S. Database System Concepts''&lt;br /&gt;
&lt;br /&gt;
[[Категория: Базы данных]]&lt;/div&gt;</summary>
		<author><name>91.143.51.202</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D0%B0%D1%86%D0%B8%D1%8F_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85._%D0%A3%D0%BF%D0%BE%D1%80%D1%8F%D0%B4%D0%BE%D1%87%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5_%D0%B8_%D1%85%D0%B5%D1%88-%D0%B8%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D1%8B&amp;diff=82034</id>
		<title>Индексация данных. Упорядоченные и хеш-индексы</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D0%B0%D1%86%D0%B8%D1%8F_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85._%D0%A3%D0%BF%D0%BE%D1%80%D1%8F%D0%B4%D0%BE%D1%87%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5_%D0%B8_%D1%85%D0%B5%D1%88-%D0%B8%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D1%8B&amp;diff=82034"/>
				<updated>2021-12-27T09:43:05Z</updated>
		
		<summary type="html">&lt;p&gt;91.143.51.202: /* Расширяемое хеширование */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Индексы ==&lt;br /&gt;
&lt;br /&gt;
Индексы нужны для того, чтобы оптимально искать нужные записи в таблице.&lt;br /&gt;
&lt;br /&gt;
Всего есть два способа найти нужные данные:&lt;br /&gt;
* Полный просмотр таблицы&lt;br /&gt;
** Последовательный перебор записей&lt;br /&gt;
** Быстро работает на маленьких таблицах, но медленно на средних и больших&lt;br /&gt;
** Если выбираем большую часть данных, то работает быстро. Иначе - медленно&lt;br /&gt;
* Индекс&lt;br /&gt;
** Произвольный набор столбцов&lt;br /&gt;
** Требуется предварительная обработка таблицы как при построении, так и при обновлении&lt;br /&gt;
** Быстрый поиск в индексе, сразу получаем указатель на запись&lt;br /&gt;
&lt;br /&gt;
На больших данных вся таблица не помещяется в память, из-за этого время работы очень сильно возрастает. &lt;br /&gt;
&lt;br /&gt;
Из-за всего вышеперечисленного, на больших данных использование полного просмотра становится на практике неприемлимым и используется индексация. На маленьких данных полный перебор работает хорошо и создание дополнительных струкрур поверх данных не окупается, поэтому может применяться на практике. &lt;br /&gt;
&lt;br /&gt;
=== Кластеризованный индекс ===&lt;br /&gt;
&lt;br /&gt;
[[Файл:Index_Clustered.png|мини|Кластеризованный индекс]]&lt;br /&gt;
&lt;br /&gt;
Если данные в таблице хранятся в порядке индекса, то такой индекс называется '''кластеризованным'''. Кластеризованный индекс позволяет увеличить скорость просмотра, так как нет дополнительной операции загрузки данных, однако так хранить данные возможно только если в таблице есть всего один индекс.&lt;br /&gt;
&lt;br /&gt;
=== Структура Индекса ===&lt;br /&gt;
&lt;br /&gt;
[[Файл:Index_Structure.png|мини|Структура индекса]]&lt;br /&gt;
&lt;br /&gt;
В общем случае индексы хранят отображение из ключей на идентификаторы записей, которые ведут на записи, которые мы загружаем&lt;br /&gt;
&lt;br /&gt;
Есть два подхода к реализации индексов: &lt;br /&gt;
* Хеш-таблицы&lt;br /&gt;
* Деревья поиска&lt;br /&gt;
&lt;br /&gt;
== Хеш-индексы == &lt;br /&gt;
&lt;br /&gt;
Хеш-функция задается разработчиком СУБД а не пользователем, чаще всего это эффективно вычисляемые хеш-функции, которые имеют гарантии статистического распределения. Атаки возможны, однако хеш-функцию легко поменять, поэтому атаки ненадежны.&lt;br /&gt;
&lt;br /&gt;
* Предварительная обработка &lt;br /&gt;
** Подсчет хешей ключей.&lt;br /&gt;
** Разбиение на корзины&lt;br /&gt;
* Поиск в индексе&lt;br /&gt;
** Просмотр корзины&lt;br /&gt;
** Несколько ключей в корзине. Коллизии могут быть, так как индекс не всегда ключ, поэтому нормально если есть повторяющиеся начения. Хеш-таблица все еще честная, но она должна понимать, что значения могут дублироваться.&lt;br /&gt;
** Если хеш-индекс является надключем, то СУБД может этим воспользоваться и гарантировать, что дублирующихся значений не будет.&lt;br /&gt;
* Заголовок помещяется в памяти&lt;br /&gt;
[[Файл:Index_Hash_Simple.png|мини|Простой хеш-индекс]]&lt;br /&gt;
&lt;br /&gt;
Однако может наступить момент, когда очередная корзина не помещается в страницу, в таком случае мы так же храним их цепочками. &lt;br /&gt;
&lt;br /&gt;
* Так как хеш-функция хорошая, то в цепочке только полезные данные&lt;br /&gt;
* Если цепочка длинная, значит этому набору столбцов соответствует много строк, значит база данных так и задумывалась.&lt;br /&gt;
&lt;br /&gt;
При этом получаем линейное время поиска&lt;br /&gt;
Но в случае если данных много, мы не можем просто увеличить число корзин и перенести данные, так как перехешировать таблицу очень долго&lt;br /&gt;
&lt;br /&gt;
[[Файл:Index_Hash_Sequence.png|мини|Цепочки страниц]]&lt;br /&gt;
&lt;br /&gt;
=== Расширяемое хеширование ===&lt;br /&gt;
&lt;br /&gt;
Изначально создаем большое количество корзин, сильно больше чем требуется. Пока мало данных Храним несколько корзин на одной странице, чтобы не аллоцировать для каждой корзины по отдельной странице.&lt;br /&gt;
* Обычно выбираем набор корзин, которые идут подряд&lt;br /&gt;
* При переполнении страницы разделенем корзины на две страницы&lt;br /&gt;
* Не работает при плохой хеш-функции, но у нас хорошая&lt;br /&gt;
&lt;br /&gt;
При переполнении страницы мы:&lt;br /&gt;
* разделяем ее на несколько страниц&lt;br /&gt;
* разделим страницы, которые на нее ссылались, на несколько групп&lt;br /&gt;
Стоимость: $1$ чтение и запись стольких страниц, на сколько мы разделили (обычно $2$)&lt;br /&gt;
* Каждой такой группе выделим по странице&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:Index_Hash_Extendable.png|мини|Расширяемое хеширование]]&lt;br /&gt;
&lt;br /&gt;
=== Побитное расширяемое хеширование ===&lt;br /&gt;
&lt;br /&gt;
*Глубина хеша $n$&lt;br /&gt;
** Создадим $2^n$ корзин&lt;br /&gt;
* Для каждой страницы хранится ее локальная глубина $k$&lt;br /&gt;
** Это значит что она хранит $2^{n−k}$ последовательных корзин на странице&lt;br /&gt;
** Может быть разной для разных страниц&lt;br /&gt;
* При переполнении происходит разделение корзин&lt;br /&gt;
** Страница глубины $k$ разделяется на две глубины $k+1$&lt;br /&gt;
&lt;br /&gt;
=== Ускоряемые запросы ===&lt;br /&gt;
&lt;br /&gt;
*Проверка существования ключа&lt;br /&gt;
**Проверка повторений (ключи)&lt;br /&gt;
**''in'' - только если есть все необходимые атрибуты&lt;br /&gt;
**''exist'' - только если есть все необходимые атрибуты&lt;br /&gt;
**''count'' - зачастую можно посчитать по индексу count, не обращаясь к самим записям&lt;br /&gt;
*Поиск по ключу&lt;br /&gt;
**Естественные соединения&lt;br /&gt;
&lt;br /&gt;
== Упорядоченные индексы ==&lt;br /&gt;
&lt;br /&gt;
Традиционно реализуются на деревьях поиска&lt;br /&gt;
&lt;br /&gt;
* Предварительная обработка&lt;br /&gt;
** Ключи упорядочиваются по возрастанию - так как ключ составной, то используем лексикографисечкое возрастание&lt;br /&gt;
* Поиск в индексе&lt;br /&gt;
** Поиск в упорядоченной последовательности&lt;br /&gt;
&lt;br /&gt;
Деревья поиска&lt;br /&gt;
* Количество операций&lt;br /&gt;
** Обычно пропорционально $O$(высоты)&lt;br /&gt;
** Так как время выполнение операций зависит от высоты, для оптимизации времени нужно минимизировать высоту&lt;br /&gt;
* Размер узла&lt;br /&gt;
** Хотим эффективно использовать страницы&lt;br /&gt;
** Сильно ветвящиеся деревья, так размер узла будет ~странице и высота будет минимальной&lt;br /&gt;
&lt;br /&gt;
=== $B$ и $B+$ деревья ===&lt;br /&gt;
&lt;br /&gt;
* $B$ деревья степени $n$&lt;br /&gt;
** От $\frac{n}{2}$ до n детей&lt;br /&gt;
** Указатели и ключи хранятся в узлах&lt;br /&gt;
* $B+$ деревья степени $n$&lt;br /&gt;
** От $\frac{n}{2}$ до $n$ детей&lt;br /&gt;
** Указатели хранятся в листьях&lt;br /&gt;
&lt;br /&gt;
* $B+$ меньше данных в узлах - сильнее ветвятся&lt;br /&gt;
* $B+$ на одну страницу глубже&lt;br /&gt;
&lt;br /&gt;
Мы храним корень и несколько первых уровней в памяти для быстрого обращения, из-за этого время работы может резко возрастать, когда заканчивается закешированные уровни.&lt;br /&gt;
&lt;br /&gt;
=== Плотные и разряженные индексы ===&lt;br /&gt;
&lt;br /&gt;
* Плотный индекс&lt;br /&gt;
** Храним ключи всех элементов&lt;br /&gt;
* Разряженные индекс&lt;br /&gt;
** Храним ключи части элементов&lt;br /&gt;
** Обычно – один на страницу, мы можем найти данные в рамках этой страницы без загрузки новых&lt;br /&gt;
** Разряженный индекс бычно используется для кластеризованных индексов&lt;br /&gt;
** Уменьшает число уровней&lt;br /&gt;
&lt;br /&gt;
Так как упорядоченных индекс хранит сами данные в узлах, а не только хеш, то чем больше индексируеммые данные, тем меньше степень ветвления&lt;br /&gt;
&lt;br /&gt;
*Строки&lt;br /&gt;
**Много данных в ключе – меньше степень ветвления&lt;br /&gt;
**Можно использовать префиксы&lt;br /&gt;
**Строки опасно использовать в качестве индекса, может сильно вырости высота дерева&lt;br /&gt;
*Суррогатные ключи&lt;br /&gt;
**Малый размер&lt;br /&gt;
**Выше эффективность&lt;br /&gt;
**Широкие и низкие деревья - хорошо&lt;br /&gt;
*Изменяющиеся данные&lt;br /&gt;
**Частое обновление индекса&lt;br /&gt;
**Уменьшение индекса&lt;br /&gt;
**Не эффективно, для уменьшения данных нужна отдельная таска&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ускоряемые запросы ===&lt;br /&gt;
* Проверка существования ключа&lt;br /&gt;
* Поиск по ключу&lt;br /&gt;
* Минимум и максимум среди значений, на которых построен ключ&lt;br /&gt;
* Диапазон &lt;br /&gt;
** Загрузка&lt;br /&gt;
** count. count * работает быстроее, так как не нужно идти по всем данным&lt;br /&gt;
* Если построен на строках, like по префиксу&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;br /&gt;
* ''Дейт К. Введение в системы баз данных (Приложение Г)''&lt;br /&gt;
* ''Кнут Д. Искусство программирования. Том 3. Сортировка и поиск''&lt;br /&gt;
* ''Silberschatz A., Korth H. F., Sudarshan S. Database System Concepts''&lt;br /&gt;
&lt;br /&gt;
[[Категория: Базы данных]]&lt;/div&gt;</summary>
		<author><name>91.143.51.202</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D0%B0%D1%86%D0%B8%D1%8F_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85._%D0%A3%D0%BF%D0%BE%D1%80%D1%8F%D0%B4%D0%BE%D1%87%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5_%D0%B8_%D1%85%D0%B5%D1%88-%D0%B8%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D1%8B&amp;diff=82031</id>
		<title>Индексация данных. Упорядоченные и хеш-индексы</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D0%B0%D1%86%D0%B8%D1%8F_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85._%D0%A3%D0%BF%D0%BE%D1%80%D1%8F%D0%B4%D0%BE%D1%87%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5_%D0%B8_%D1%85%D0%B5%D1%88-%D0%B8%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D1%8B&amp;diff=82031"/>
				<updated>2021-12-27T09:38:19Z</updated>
		
		<summary type="html">&lt;p&gt;91.143.51.202: /* Хеш-индексы */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Индексы ==&lt;br /&gt;
&lt;br /&gt;
Индексы нужны для того, чтобы оптимально искать нужные записи в таблице.&lt;br /&gt;
&lt;br /&gt;
Всего есть два способа найти нужные данные:&lt;br /&gt;
* Полный просмотр таблицы&lt;br /&gt;
** Последовательный перебор записей&lt;br /&gt;
** Быстро работает на маленьких таблицах, но медленно на средних и больших&lt;br /&gt;
** Если выбираем большую часть данных, то работает быстро. Иначе - медленно&lt;br /&gt;
* Индекс&lt;br /&gt;
** Произвольный набор столбцов&lt;br /&gt;
** Требуется предварительная обработка таблицы как при построении, так и при обновлении&lt;br /&gt;
** Быстрый поиск в индексе, сразу получаем указатель на запись&lt;br /&gt;
&lt;br /&gt;
На больших данных вся таблица не помещяется в память, из-за этого время работы очень сильно возрастает. &lt;br /&gt;
&lt;br /&gt;
Из-за всего вышеперечисленного, на больших данных использование полного просмотра становится на практике неприемлимым и используется индексация. На маленьких данных полный перебор работает хорошо и создание дополнительных струкрур поверх данных не окупается, поэтому может применяться на практике. &lt;br /&gt;
&lt;br /&gt;
=== Кластеризованный индекс ===&lt;br /&gt;
&lt;br /&gt;
[[Файл:Index_Clustered.png|мини|Кластеризованный индекс]]&lt;br /&gt;
&lt;br /&gt;
Если данные в таблице хранятся в порядке индекса, то такой индекс называется '''кластеризованным'''. Кластеризованный индекс позволяет увеличить скорость просмотра, так как нет дополнительной операции загрузки данных, однако так хранить данные возможно только если в таблице есть всего один индекс.&lt;br /&gt;
&lt;br /&gt;
=== Структура Индекса ===&lt;br /&gt;
&lt;br /&gt;
[[Файл:Index_Structure.png|мини|Структура индекса]]&lt;br /&gt;
&lt;br /&gt;
В общем случае индексы хранят отображение из ключей на идентификаторы записей, которые ведут на записи, которые мы загружаем&lt;br /&gt;
&lt;br /&gt;
Есть два подхода к реализации индексов: &lt;br /&gt;
* Хеш-таблицы&lt;br /&gt;
* Деревья поиска&lt;br /&gt;
&lt;br /&gt;
== Хеш-индексы == &lt;br /&gt;
&lt;br /&gt;
Хеш-функция задается разработчиком СУБД а не пользователем, чаще всего это эффективно вычисляемые хеш-функции, которые имеют гарантии статистического распределения. Атаки возможны, однако хеш-функцию легко поменять, поэтому атаки ненадежны.&lt;br /&gt;
&lt;br /&gt;
* Предварительная обработка &lt;br /&gt;
** Подсчет хешей ключей.&lt;br /&gt;
** Разбиение на корзины&lt;br /&gt;
* Поиск в индексе&lt;br /&gt;
** Просмотр корзины&lt;br /&gt;
** Несколько ключей в корзине. Коллизии могут быть, так как индекс не всегда ключ, поэтому нормально если есть повторяющиеся начения. Хеш-таблица все еще честная, но она должна понимать, что значения могут дублироваться.&lt;br /&gt;
** Если хеш-индекс является надключем, то СУБД может этим воспользоваться и гарантировать, что дублирующихся значений не будет.&lt;br /&gt;
* Заголовок помещяется в памяти&lt;br /&gt;
[[Файл:Index_Hash_Simple.png|мини|Простой хеш-индекс]]&lt;br /&gt;
&lt;br /&gt;
Однако может наступить момент, когда очередная корзина не помещается в страницу, в таком случае мы так же храним их цепочками. &lt;br /&gt;
&lt;br /&gt;
* Так как хеш-функция хорошая, то в цепочке только полезные данные&lt;br /&gt;
* Если цепочка длинная, значит этому набору столбцов соответствует много строк, значит база данных так и задумывалась.&lt;br /&gt;
&lt;br /&gt;
При этом получаем линейное время поиска&lt;br /&gt;
Но в случае если данных много, мы не можем просто увеличить число корзин и перенести данные, так как перехешировать таблицу очень долго&lt;br /&gt;
&lt;br /&gt;
[[Файл:Index_Hash_Sequence.png|мини|Цепочки страниц]]&lt;br /&gt;
&lt;br /&gt;
=== Расширяемое хеширование ===&lt;br /&gt;
&lt;br /&gt;
* Большое количество корзин, сильно больше чем требуется&lt;br /&gt;
* Несколько корзин на одной странице, чтобы не аллоцировать для каждой корзины страницу&lt;br /&gt;
** Обычно - последовательных&lt;br /&gt;
** Разделение корзин при переполнении страницы&lt;br /&gt;
* Не работает при плохой хеш-функции, но у нас хорошая&lt;br /&gt;
&lt;br /&gt;
При переполнении страницы мы:&lt;br /&gt;
* разделяем ее на несколько страниц&lt;br /&gt;
* разделим страницы, которые на нее ссылались, на несколько групп&lt;br /&gt;
* Каждой такой группе выделим по странице&lt;br /&gt;
&lt;br /&gt;
Стоимость: $1$ чтение и запись стольких страниц, на сколько мы разделили (обычно $2$)&lt;br /&gt;
&lt;br /&gt;
[[Файл:Index_Hash_Extendable.png|мини|Расширяемое хеширование]]&lt;br /&gt;
&lt;br /&gt;
=== Побитное расширяемое хеширование ===&lt;br /&gt;
&lt;br /&gt;
*Глубина хеша $n$&lt;br /&gt;
** Создадим $2^n$ корзин&lt;br /&gt;
* Для каждой страницы хранится ее локальная глубина $k$&lt;br /&gt;
** Это значит что она хранит $2^{n−k}$ последовательных корзин на странице&lt;br /&gt;
** Может быть разной для разных страниц&lt;br /&gt;
* При переполнении происходит разделение корзин&lt;br /&gt;
** Страница глубины $k$ разделяется на две глубины $k+1$&lt;br /&gt;
&lt;br /&gt;
=== Ускоряемые запросы ===&lt;br /&gt;
&lt;br /&gt;
*Проверка существования ключа&lt;br /&gt;
**Проверка повторений (ключи)&lt;br /&gt;
**''in'' - только если есть все необходимые атрибуты&lt;br /&gt;
**''exist'' - только если есть все необходимые атрибуты&lt;br /&gt;
**''count'' - зачастую можно посчитать по индексу count, не обращаясь к самим записям&lt;br /&gt;
*Поиск по ключу&lt;br /&gt;
**Естественные соединения&lt;br /&gt;
&lt;br /&gt;
== Упорядоченные индексы ==&lt;br /&gt;
&lt;br /&gt;
Традиционно реализуются на деревьях поиска&lt;br /&gt;
&lt;br /&gt;
* Предварительная обработка&lt;br /&gt;
** Ключи упорядочиваются по возрастанию - так как ключ составной, то используем лексикографисечкое возрастание&lt;br /&gt;
* Поиск в индексе&lt;br /&gt;
** Поиск в упорядоченной последовательности&lt;br /&gt;
&lt;br /&gt;
Деревья поиска&lt;br /&gt;
* Количество операций&lt;br /&gt;
** Обычно пропорционально $O$(высоты)&lt;br /&gt;
** Так как время выполнение операций зависит от высоты, для оптимизации времени нужно минимизировать высоту&lt;br /&gt;
* Размер узла&lt;br /&gt;
** Хотим эффективно использовать страницы&lt;br /&gt;
** Сильно ветвящиеся деревья, так размер узла будет ~странице и высота будет минимальной&lt;br /&gt;
&lt;br /&gt;
=== $B$ и $B+$ деревья ===&lt;br /&gt;
&lt;br /&gt;
* $B$ деревья степени $n$&lt;br /&gt;
** От $\frac{n}{2}$ до n детей&lt;br /&gt;
** Указатели и ключи хранятся в узлах&lt;br /&gt;
* $B+$ деревья степени $n$&lt;br /&gt;
** От $\frac{n}{2}$ до $n$ детей&lt;br /&gt;
** Указатели хранятся в листьях&lt;br /&gt;
&lt;br /&gt;
* $B+$ меньше данных в узлах - сильнее ветвятся&lt;br /&gt;
* $B+$ на одну страницу глубже&lt;br /&gt;
&lt;br /&gt;
Мы храним корень и несколько первых уровней в памяти для быстрого обращения, из-за этого время работы может резко возрастать, когда заканчивается закешированные уровни.&lt;br /&gt;
&lt;br /&gt;
=== Плотные и разряженные индексы ===&lt;br /&gt;
&lt;br /&gt;
* Плотный индекс&lt;br /&gt;
** Храним ключи всех элементов&lt;br /&gt;
* Разряженные индекс&lt;br /&gt;
** Храним ключи части элементов&lt;br /&gt;
** Обычно – один на страницу, мы можем найти данные в рамках этой страницы без загрузки новых&lt;br /&gt;
** Разряженный индекс бычно используется для кластеризованных индексов&lt;br /&gt;
** Уменьшает число уровней&lt;br /&gt;
&lt;br /&gt;
Так как упорядоченных индекс хранит сами данные в узлах, а не только хеш, то чем больше индексируеммые данные, тем меньше степень ветвления&lt;br /&gt;
&lt;br /&gt;
*Строки&lt;br /&gt;
**Много данных в ключе – меньше степень ветвления&lt;br /&gt;
**Можно использовать префиксы&lt;br /&gt;
**Строки опасно использовать в качестве индекса, может сильно вырости высота дерева&lt;br /&gt;
*Суррогатные ключи&lt;br /&gt;
**Малый размер&lt;br /&gt;
**Выше эффективность&lt;br /&gt;
**Широкие и низкие деревья - хорошо&lt;br /&gt;
*Изменяющиеся данные&lt;br /&gt;
**Частое обновление индекса&lt;br /&gt;
**Уменьшение индекса&lt;br /&gt;
**Не эффективно, для уменьшения данных нужна отдельная таска&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ускоряемые запросы ===&lt;br /&gt;
* Проверка существования ключа&lt;br /&gt;
* Поиск по ключу&lt;br /&gt;
* Минимум и максимум среди значений, на которых построен ключ&lt;br /&gt;
* Диапазон &lt;br /&gt;
** Загрузка&lt;br /&gt;
** count. count * работает быстроее, так как не нужно идти по всем данным&lt;br /&gt;
* Если построен на строках, like по префиксу&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;br /&gt;
* ''Дейт К. Введение в системы баз данных (Приложение Г)''&lt;br /&gt;
* ''Кнут Д. Искусство программирования. Том 3. Сортировка и поиск''&lt;br /&gt;
* ''Silberschatz A., Korth H. F., Sudarshan S. Database System Concepts''&lt;br /&gt;
&lt;br /&gt;
[[Категория: Базы данных]]&lt;/div&gt;</summary>
		<author><name>91.143.51.202</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D0%B0%D1%86%D0%B8%D1%8F_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85._%D0%A3%D0%BF%D0%BE%D1%80%D1%8F%D0%B4%D0%BE%D1%87%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5_%D0%B8_%D1%85%D0%B5%D1%88-%D0%B8%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D1%8B&amp;diff=82019</id>
		<title>Индексация данных. Упорядоченные и хеш-индексы</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D0%B0%D1%86%D0%B8%D1%8F_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85._%D0%A3%D0%BF%D0%BE%D1%80%D1%8F%D0%B4%D0%BE%D1%87%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5_%D0%B8_%D1%85%D0%B5%D1%88-%D0%B8%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D1%8B&amp;diff=82019"/>
				<updated>2021-12-27T09:28:34Z</updated>
		
		<summary type="html">&lt;p&gt;91.143.51.202: /* Хеш-индексы */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Индексы ==&lt;br /&gt;
&lt;br /&gt;
Индексы нужны для того, чтобы оптимально искать нужные записи в таблице.&lt;br /&gt;
&lt;br /&gt;
Всего есть два способа найти нужные данные:&lt;br /&gt;
* Полный просмотр таблицы&lt;br /&gt;
** Последовательный перебор записей&lt;br /&gt;
** Быстро работает на маленьких таблицах, но медленно на средних и больших&lt;br /&gt;
** Если выбираем большую часть данных, то работает быстро. Иначе - медленно&lt;br /&gt;
* Индекс&lt;br /&gt;
** Произвольный набор столбцов&lt;br /&gt;
** Требуется предварительная обработка таблицы как при построении, так и при обновлении&lt;br /&gt;
** Быстрый поиск в индексе, сразу получаем указатель на запись&lt;br /&gt;
&lt;br /&gt;
На больших данных вся таблица не помещяется в память, из-за этого время работы очень сильно возрастает. &lt;br /&gt;
&lt;br /&gt;
Из-за всего вышеперечисленного, на больших данных использование полного просмотра становится на практике неприемлимым и используется индексация. На маленьких данных полный перебор работает хорошо и создание дополнительных струкрур поверх данных не окупается, поэтому может применяться на практике. &lt;br /&gt;
&lt;br /&gt;
=== Кластеризованный индекс ===&lt;br /&gt;
&lt;br /&gt;
[[Файл:Index_Clustered.png|мини|Кластеризованный индекс]]&lt;br /&gt;
&lt;br /&gt;
Если данные в таблице хранятся в порядке индекса, то такой индекс называется '''кластеризованным'''. Кластеризованный индекс позволяет увеличить скорость просмотра, так как нет дополнительной операции загрузки данных, однако так хранить данные возможно только если в таблице есть всего один индекс.&lt;br /&gt;
&lt;br /&gt;
=== Структура Индекса ===&lt;br /&gt;
&lt;br /&gt;
[[Файл:Index_Structure.png|мини|Структура индекса]]&lt;br /&gt;
&lt;br /&gt;
В общем случае индексы хранят отображение из ключей на идентификаторы записей, которые ведут на записи, которые мы загружаем&lt;br /&gt;
&lt;br /&gt;
Есть два подхода к реализации индексов: &lt;br /&gt;
* Хеш-таблицы&lt;br /&gt;
* Деревья поиска&lt;br /&gt;
&lt;br /&gt;
== Хеш-индексы == &lt;br /&gt;
&lt;br /&gt;
Хеш-функция задается разработчиком СУБД а не пользователем, чаще всего это эффективно вычисляемые хеш-функции, которые имеют гарантии статистического распределения. Атаки возможны, однако хеш-функцию легко поменять, поэтому атаки ненадежны.&lt;br /&gt;
&lt;br /&gt;
* Предварительная обработка &lt;br /&gt;
** Подсчет хешей ключей.&lt;br /&gt;
** Разбиение на корзины&lt;br /&gt;
* Поиск в индексе&lt;br /&gt;
** Просмотр корзины&lt;br /&gt;
** Несколько ключей в корзине. Коллизии могут быть, так как индекс не всегда ключ, поэтому нормально если есть повторяющиеся начения. Хеш-таблица все еще честная, но она должна понимать, что значения могут дублироваться.&lt;br /&gt;
** Если хеш-индекс является надключем, то СУБД может этим воспользоваться и гарантировать, что дублирующихся значений не будет.&lt;br /&gt;
* Заголовок помещяется в памяти&lt;br /&gt;
[[Файл:Index_Hash_Simple.png|мини|Простой хеш-индекс]]&lt;br /&gt;
&lt;br /&gt;
Однако может наступить момент, когда очередная корзина не помещается в страницу, в таком случае мы так же храним их цепочками. &lt;br /&gt;
&lt;br /&gt;
* Так как хеш-функция хорошая, то в цепочке только полезные данные&lt;br /&gt;
* Если цепочка длинная, значит этому набору столбцов соответствует много строк, значит база данных так и задумывалась.&lt;br /&gt;
&lt;br /&gt;
При этом получаем&lt;br /&gt;
* Линейное время поиска&lt;br /&gt;
* В случае, если данных много, мы не можем просто увеличить число корзин и перенести данные, так как перехешировать таблицу очень долго&lt;br /&gt;
&lt;br /&gt;
[[Файл:Index_Hash_Sequence.png|мини|Цепочки страниц]]&lt;br /&gt;
&lt;br /&gt;
=== Расширяемое хеширование ===&lt;br /&gt;
&lt;br /&gt;
* Большое количество корзин, сильно больше чем требуется&lt;br /&gt;
* Несколько корзин на одной странице, чтобы не аллоцировать для каждой корзины страницу&lt;br /&gt;
** Обычно - последовательных&lt;br /&gt;
** Разделение корзин при переполнении страницы&lt;br /&gt;
* Не работает при плохой хеш-функции, но у нас хорошая&lt;br /&gt;
&lt;br /&gt;
При переполнении страницы мы:&lt;br /&gt;
* разделяем ее на несколько страниц&lt;br /&gt;
* разделим страницы, которые на нее ссылались, на несколько групп&lt;br /&gt;
* Каждой такой группе выделим по странице&lt;br /&gt;
&lt;br /&gt;
Стоимость: $1$ чтение и запись стольких страниц, на сколько мы разделили (обычно $2$)&lt;br /&gt;
&lt;br /&gt;
[[Файл:Index_Hash_Extendable.png|мини|Расширяемое хеширование]]&lt;br /&gt;
&lt;br /&gt;
=== Побитное расширяемое хеширование ===&lt;br /&gt;
&lt;br /&gt;
*Глубина хеша $n$&lt;br /&gt;
** Создадим $2^n$ корзин&lt;br /&gt;
* Для каждой страницы хранится ее локальная глубина $k$&lt;br /&gt;
** Это значит что она хранит $2^{n−k}$ последовательных корзин на странице&lt;br /&gt;
** Может быть разной для разных страниц&lt;br /&gt;
* При переполнении происходит разделение корзин&lt;br /&gt;
** Страница глубины $k$ разделяется на две глубины $k+1$&lt;br /&gt;
&lt;br /&gt;
=== Ускоряемые запросы ===&lt;br /&gt;
&lt;br /&gt;
*Проверка существования ключа&lt;br /&gt;
**Проверка повторений (ключи)&lt;br /&gt;
**''in'' - только если есть все необходимые атрибуты&lt;br /&gt;
**''exist'' - только если есть все необходимые атрибуты&lt;br /&gt;
**''count'' - зачастую можно посчитать по индексу count, не обращаясь к самим записям&lt;br /&gt;
*Поиск по ключу&lt;br /&gt;
**Естественные соединения&lt;br /&gt;
&lt;br /&gt;
== Упорядоченные индексы ==&lt;br /&gt;
&lt;br /&gt;
Традиционно реализуются на деревьях поиска&lt;br /&gt;
&lt;br /&gt;
* Предварительная обработка&lt;br /&gt;
** Ключи упорядочиваются по возрастанию - так как ключ составной, то используем лексикографисечкое возрастание&lt;br /&gt;
* Поиск в индексе&lt;br /&gt;
** Поиск в упорядоченной последовательности&lt;br /&gt;
&lt;br /&gt;
Деревья поиска&lt;br /&gt;
* Количество операций&lt;br /&gt;
** Обычно пропорционально $O$(высоты)&lt;br /&gt;
** Так как время выполнение операций зависит от высоты, для оптимизации времени нужно минимизировать высоту&lt;br /&gt;
* Размер узла&lt;br /&gt;
** Хотим эффективно использовать страницы&lt;br /&gt;
** Сильно ветвящиеся деревья, так размер узла будет ~странице и высота будет минимальной&lt;br /&gt;
&lt;br /&gt;
=== $B$ и $B+$ деревья ===&lt;br /&gt;
&lt;br /&gt;
* $B$ деревья степени $n$&lt;br /&gt;
** От $\frac{n}{2}$ до n детей&lt;br /&gt;
** Указатели и ключи хранятся в узлах&lt;br /&gt;
* $B+$ деревья степени $n$&lt;br /&gt;
** От $\frac{n}{2}$ до $n$ детей&lt;br /&gt;
** Указатели хранятся в листьях&lt;br /&gt;
&lt;br /&gt;
* $B+$ меньше данных в узлах - сильнее ветвятся&lt;br /&gt;
* $B+$ на одну страницу глубже&lt;br /&gt;
&lt;br /&gt;
Мы храним корень и несколько первых уровней в памяти для быстрого обращения, из-за этого время работы может резко возрастать, когда заканчивается закешированные уровни.&lt;br /&gt;
&lt;br /&gt;
=== Плотные и разряженные индексы ===&lt;br /&gt;
&lt;br /&gt;
* Плотный индекс&lt;br /&gt;
** Храним ключи всех элементов&lt;br /&gt;
* Разряженные индекс&lt;br /&gt;
** Храним ключи части элементов&lt;br /&gt;
** Обычно – один на страницу, мы можем найти данные в рамках этой страницы без загрузки новых&lt;br /&gt;
** Разряженный индекс бычно используется для кластеризованных индексов&lt;br /&gt;
** Уменьшает число уровней&lt;br /&gt;
&lt;br /&gt;
Так как упорядоченных индекс хранит сами данные в узлах, а не только хеш, то чем больше индексируеммые данные, тем меньше степень ветвления&lt;br /&gt;
&lt;br /&gt;
*Строки&lt;br /&gt;
**Много данных в ключе – меньше степень ветвления&lt;br /&gt;
**Можно использовать префиксы&lt;br /&gt;
**Строки опасно использовать в качестве индекса, может сильно вырости высота дерева&lt;br /&gt;
*Суррогатные ключи&lt;br /&gt;
**Малый размер&lt;br /&gt;
**Выше эффективность&lt;br /&gt;
**Широкие и низкие деревья - хорошо&lt;br /&gt;
*Изменяющиеся данные&lt;br /&gt;
**Частое обновление индекса&lt;br /&gt;
**Уменьшение индекса&lt;br /&gt;
**Не эффективно, для уменьшения данных нужна отдельная таска&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ускоряемые запросы ===&lt;br /&gt;
* Проверка существования ключа&lt;br /&gt;
* Поиск по ключу&lt;br /&gt;
* Минимум и максимум среди значений, на которых построен ключ&lt;br /&gt;
* Диапазон &lt;br /&gt;
** Загрузка&lt;br /&gt;
** count. count * работает быстроее, так как не нужно идти по всем данным&lt;br /&gt;
* Если построен на строках, like по префиксу&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;br /&gt;
* ''Дейт К. Введение в системы баз данных (Приложение Г)''&lt;br /&gt;
* ''Кнут Д. Искусство программирования. Том 3. Сортировка и поиск''&lt;br /&gt;
* ''Silberschatz A., Korth H. F., Sudarshan S. Database System Concepts''&lt;br /&gt;
&lt;br /&gt;
[[Категория: Базы данных]]&lt;/div&gt;</summary>
		<author><name>91.143.51.202</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D0%B0%D1%86%D0%B8%D1%8F_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85._%D0%A3%D0%BF%D0%BE%D1%80%D1%8F%D0%B4%D0%BE%D1%87%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5_%D0%B8_%D1%85%D0%B5%D1%88-%D0%B8%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D1%8B&amp;diff=82016</id>
		<title>Индексация данных. Упорядоченные и хеш-индексы</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D0%B0%D1%86%D0%B8%D1%8F_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85._%D0%A3%D0%BF%D0%BE%D1%80%D1%8F%D0%B4%D0%BE%D1%87%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5_%D0%B8_%D1%85%D0%B5%D1%88-%D0%B8%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D1%8B&amp;diff=82016"/>
				<updated>2021-12-27T09:21:00Z</updated>
		
		<summary type="html">&lt;p&gt;91.143.51.202: /* Кластеризованный индекс */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Индексы ==&lt;br /&gt;
&lt;br /&gt;
Индексы нужны для того, чтобы оптимально искать нужные записи в таблице.&lt;br /&gt;
&lt;br /&gt;
Всего есть два способа найти нужные данные:&lt;br /&gt;
* Полный просмотр таблицы&lt;br /&gt;
** Последовательный перебор записей&lt;br /&gt;
** Быстро работает на маленьких таблицах, но медленно на средних и больших&lt;br /&gt;
** Если выбираем большую часть данных, то работает быстро. Иначе - медленно&lt;br /&gt;
* Индекс&lt;br /&gt;
** Произвольный набор столбцов&lt;br /&gt;
** Требуется предварительная обработка таблицы как при построении, так и при обновлении&lt;br /&gt;
** Быстрый поиск в индексе, сразу получаем указатель на запись&lt;br /&gt;
&lt;br /&gt;
На больших данных вся таблица не помещяется в память, из-за этого время работы очень сильно возрастает. &lt;br /&gt;
&lt;br /&gt;
Из-за всего вышеперечисленного, на больших данных использование полного просмотра становится на практике неприемлимым и используется индексация. На маленьких данных полный перебор работает хорошо и создание дополнительных струкрур поверх данных не окупается, поэтому может применяться на практике. &lt;br /&gt;
&lt;br /&gt;
=== Кластеризованный индекс ===&lt;br /&gt;
&lt;br /&gt;
[[Файл:Index_Clustered.png|мини|Кластеризованный индекс]]&lt;br /&gt;
&lt;br /&gt;
Если данные в таблице хранятся в порядке индекса, то такой индекс называется '''кластеризованным'''. Кластеризованный индекс позволяет увеличить скорость просмотра, так как нет дополнительной операции загрузки данных, однако так хранить данные возможно только если в таблице есть всего один индекс.&lt;br /&gt;
&lt;br /&gt;
=== Структура Индекса ===&lt;br /&gt;
&lt;br /&gt;
[[Файл:Index_Structure.png|мини|Структура индекса]]&lt;br /&gt;
&lt;br /&gt;
В общем случае индексы хранят отображение из ключей на идентификаторы записей, которые ведут на записи, которые мы загружаем&lt;br /&gt;
&lt;br /&gt;
Есть два подхода к реализации индексов: &lt;br /&gt;
* Хеш-таблицы&lt;br /&gt;
* Деревья поиска&lt;br /&gt;
&lt;br /&gt;
== Хеш-индексы == &lt;br /&gt;
* Предварительная обработка&lt;br /&gt;
** Подсчет хешей ключей. Хеш-функция задается разработчиком СУБД, что дает нам гарантии хорошего статистического распределения.&lt;br /&gt;
** Разбиение на корзины&lt;br /&gt;
* Поиск в индексе&lt;br /&gt;
** Просмотр корзины&lt;br /&gt;
** Несколько ключей в корзине. Коллизии могут быть, так как индекс не всегда ключ.&lt;br /&gt;
* Заголовок помещяется в памяти&lt;br /&gt;
[[Файл:Index_Hash_Simple.png|мини|Простой хеш-индекс]]&lt;br /&gt;
&lt;br /&gt;
Однако может наступить момент, когда очередная корзина не помещается в страницу, в таком случае мы так же храним их цепочками. &lt;br /&gt;
&lt;br /&gt;
* Так как хеш-функция хорошая, то в цепочке только полезные данные&lt;br /&gt;
* Если цепочка длинная, значит этому набору столбцов соответствует много строк, значит база данных так и задумывалась.&lt;br /&gt;
&lt;br /&gt;
При этом получаем&lt;br /&gt;
* Линейное время поиска&lt;br /&gt;
* В случае, если данных много, мы не можем просто увеличить число корзин и перенести данные, так как перехешировать таблицу очень долго&lt;br /&gt;
&lt;br /&gt;
[[Файл:Index_Hash_Sequence.png|мини|Цепочки страниц]]&lt;br /&gt;
&lt;br /&gt;
=== Расширяемое хеширование ===&lt;br /&gt;
&lt;br /&gt;
* Большое количество корзин, сильно больше чем требуется&lt;br /&gt;
* Несколько корзин на одной странице, чтобы не аллоцировать для каждой корзины страницу&lt;br /&gt;
** Обычно - последовательных&lt;br /&gt;
** Разделение корзин при переполнении страницы&lt;br /&gt;
* Не работает при плохой хеш-функции, но у нас хорошая&lt;br /&gt;
&lt;br /&gt;
При переполнении страницы мы:&lt;br /&gt;
* разделяем ее на несколько страниц&lt;br /&gt;
* разделим страницы, которые на нее ссылались, на несколько групп&lt;br /&gt;
* Каждой такой группе выделим по странице&lt;br /&gt;
&lt;br /&gt;
Стоимость: $1$ чтение и запись стольких страниц, на сколько мы разделили (обычно $2$)&lt;br /&gt;
&lt;br /&gt;
[[Файл:Index_Hash_Extendable.png|мини|Расширяемое хеширование]]&lt;br /&gt;
&lt;br /&gt;
=== Побитное расширяемое хеширование ===&lt;br /&gt;
&lt;br /&gt;
*Глубина хеша $n$&lt;br /&gt;
** Создадим $2^n$ корзин&lt;br /&gt;
* Для каждой страницы хранится ее локальная глубина $k$&lt;br /&gt;
** Это значит что она хранит $2^{n−k}$ последовательных корзин на странице&lt;br /&gt;
** Может быть разной для разных страниц&lt;br /&gt;
* При переполнении происходит разделение корзин&lt;br /&gt;
** Страница глубины $k$ разделяется на две глубины $k+1$&lt;br /&gt;
&lt;br /&gt;
=== Ускоряемые запросы ===&lt;br /&gt;
&lt;br /&gt;
*Проверка существования ключа&lt;br /&gt;
**Проверка повторений (ключи)&lt;br /&gt;
**''in'' - только если есть все необходимые атрибуты&lt;br /&gt;
**''exist'' - только если есть все необходимые атрибуты&lt;br /&gt;
**''count'' - зачастую можно посчитать по индексу count, не обращаясь к самим записям&lt;br /&gt;
*Поиск по ключу&lt;br /&gt;
**Естественные соединения&lt;br /&gt;
&lt;br /&gt;
== Упорядоченные индексы ==&lt;br /&gt;
&lt;br /&gt;
Традиционно реализуются на деревьях поиска&lt;br /&gt;
&lt;br /&gt;
* Предварительная обработка&lt;br /&gt;
** Ключи упорядочиваются по возрастанию - так как ключ составной, то используем лексикографисечкое возрастание&lt;br /&gt;
* Поиск в индексе&lt;br /&gt;
** Поиск в упорядоченной последовательности&lt;br /&gt;
&lt;br /&gt;
Деревья поиска&lt;br /&gt;
* Количество операций&lt;br /&gt;
** Обычно пропорционально $O$(высоты)&lt;br /&gt;
** Так как время выполнение операций зависит от высоты, для оптимизации времени нужно минимизировать высоту&lt;br /&gt;
* Размер узла&lt;br /&gt;
** Хотим эффективно использовать страницы&lt;br /&gt;
** Сильно ветвящиеся деревья, так размер узла будет ~странице и высота будет минимальной&lt;br /&gt;
&lt;br /&gt;
=== $B$ и $B+$ деревья ===&lt;br /&gt;
&lt;br /&gt;
* $B$ деревья степени $n$&lt;br /&gt;
** От $\frac{n}{2}$ до n детей&lt;br /&gt;
** Указатели и ключи хранятся в узлах&lt;br /&gt;
* $B+$ деревья степени $n$&lt;br /&gt;
** От $\frac{n}{2}$ до $n$ детей&lt;br /&gt;
** Указатели хранятся в листьях&lt;br /&gt;
&lt;br /&gt;
* $B+$ меньше данных в узлах - сильнее ветвятся&lt;br /&gt;
* $B+$ на одну страницу глубже&lt;br /&gt;
&lt;br /&gt;
Мы храним корень и несколько первых уровней в памяти для быстрого обращения, из-за этого время работы может резко возрастать, когда заканчивается закешированные уровни.&lt;br /&gt;
&lt;br /&gt;
=== Плотные и разряженные индексы ===&lt;br /&gt;
&lt;br /&gt;
* Плотный индекс&lt;br /&gt;
** Храним ключи всех элементов&lt;br /&gt;
* Разряженные индекс&lt;br /&gt;
** Храним ключи части элементов&lt;br /&gt;
** Обычно – один на страницу, мы можем найти данные в рамках этой страницы без загрузки новых&lt;br /&gt;
** Разряженный индекс бычно используется для кластеризованных индексов&lt;br /&gt;
** Уменьшает число уровней&lt;br /&gt;
&lt;br /&gt;
Так как упорядоченных индекс хранит сами данные в узлах, а не только хеш, то чем больше индексируеммые данные, тем меньше степень ветвления&lt;br /&gt;
&lt;br /&gt;
*Строки&lt;br /&gt;
**Много данных в ключе – меньше степень ветвления&lt;br /&gt;
**Можно использовать префиксы&lt;br /&gt;
**Строки опасно использовать в качестве индекса, может сильно вырости высота дерева&lt;br /&gt;
*Суррогатные ключи&lt;br /&gt;
**Малый размер&lt;br /&gt;
**Выше эффективность&lt;br /&gt;
**Широкие и низкие деревья - хорошо&lt;br /&gt;
*Изменяющиеся данные&lt;br /&gt;
**Частое обновление индекса&lt;br /&gt;
**Уменьшение индекса&lt;br /&gt;
**Не эффективно, для уменьшения данных нужна отдельная таска&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ускоряемые запросы ===&lt;br /&gt;
* Проверка существования ключа&lt;br /&gt;
* Поиск по ключу&lt;br /&gt;
* Минимум и максимум среди значений, на которых построен ключ&lt;br /&gt;
* Диапазон &lt;br /&gt;
** Загрузка&lt;br /&gt;
** count. count * работает быстроее, так как не нужно идти по всем данным&lt;br /&gt;
* Если построен на строках, like по префиксу&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;br /&gt;
* ''Дейт К. Введение в системы баз данных (Приложение Г)''&lt;br /&gt;
* ''Кнут Д. Искусство программирования. Том 3. Сортировка и поиск''&lt;br /&gt;
* ''Silberschatz A., Korth H. F., Sudarshan S. Database System Concepts''&lt;br /&gt;
&lt;br /&gt;
[[Категория: Базы данных]]&lt;/div&gt;</summary>
		<author><name>91.143.51.202</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D0%B0%D1%86%D0%B8%D1%8F_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85._%D0%A3%D0%BF%D0%BE%D1%80%D1%8F%D0%B4%D0%BE%D1%87%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5_%D0%B8_%D1%85%D0%B5%D1%88-%D0%B8%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D1%8B&amp;diff=82015</id>
		<title>Индексация данных. Упорядоченные и хеш-индексы</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D0%B0%D1%86%D0%B8%D1%8F_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85._%D0%A3%D0%BF%D0%BE%D1%80%D1%8F%D0%B4%D0%BE%D1%87%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5_%D0%B8_%D1%85%D0%B5%D1%88-%D0%B8%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D1%8B&amp;diff=82015"/>
				<updated>2021-12-27T09:14:56Z</updated>
		
		<summary type="html">&lt;p&gt;91.143.51.202: /* Индексы */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Индексы ==&lt;br /&gt;
&lt;br /&gt;
Индексы нужны для того, чтобы оптимально искать нужные записи в таблице.&lt;br /&gt;
&lt;br /&gt;
Всего есть два способа найти нужные данные:&lt;br /&gt;
* Полный просмотр таблицы&lt;br /&gt;
** Последовательный перебор записей&lt;br /&gt;
** Быстро работает на маленьких таблицах, но медленно на средних и больших&lt;br /&gt;
** Если выбираем большую часть данных, то работает быстро. Иначе - медленно&lt;br /&gt;
* Индекс&lt;br /&gt;
** Произвольный набор столбцов&lt;br /&gt;
** Требуется предварительная обработка таблицы как при построении, так и при обновлении&lt;br /&gt;
** Быстрый поиск в индексе, сразу получаем указатель на запись&lt;br /&gt;
&lt;br /&gt;
На больших данных вся таблица не помещяется в память, из-за этого время работы очень сильно возрастает. &lt;br /&gt;
&lt;br /&gt;
Из-за всего вышеперечисленного, на больших данных использование полного просмотра становится на практике неприемлимым и используется индексация. На маленьких данных полный перебор работает хорошо и создание дополнительных струкрур поверх данных не окупается, поэтому может применяться на практике. &lt;br /&gt;
&lt;br /&gt;
=== Кластеризованный индекс ===&lt;br /&gt;
&lt;br /&gt;
[[Файл:Index_Clustered.png|мини|Кластеризованный индекс]]&lt;br /&gt;
&lt;br /&gt;
Если данные в таблице хранятся в порядке индекса, то такой индекс называется '''кластеризованным'''. Кластеризованный индекс позволяет увеличить скорость просмотра, однако так хранить данные возможно только если в таблице есть всего один индекс.&lt;br /&gt;
&lt;br /&gt;
=== Структура Индекса ===&lt;br /&gt;
&lt;br /&gt;
[[Файл:Index_Structure.png|мини|Структура индекса]]&lt;br /&gt;
&lt;br /&gt;
В общем случае индексы хранят отображение из ключей на идентификаторы записей, которые ведут на записи, которые мы загружаем&lt;br /&gt;
&lt;br /&gt;
Есть два подхода к реализации индексов: &lt;br /&gt;
* Хеш-таблицы&lt;br /&gt;
* Деревья поиска&lt;br /&gt;
&lt;br /&gt;
== Хеш-индексы == &lt;br /&gt;
* Предварительная обработка&lt;br /&gt;
** Подсчет хешей ключей. Хеш-функция задается разработчиком СУБД, что дает нам гарантии хорошего статистического распределения.&lt;br /&gt;
** Разбиение на корзины&lt;br /&gt;
* Поиск в индексе&lt;br /&gt;
** Просмотр корзины&lt;br /&gt;
** Несколько ключей в корзине. Коллизии могут быть, так как индекс не всегда ключ.&lt;br /&gt;
* Заголовок помещяется в памяти&lt;br /&gt;
[[Файл:Index_Hash_Simple.png|мини|Простой хеш-индекс]]&lt;br /&gt;
&lt;br /&gt;
Однако может наступить момент, когда очередная корзина не помещается в страницу, в таком случае мы так же храним их цепочками. &lt;br /&gt;
&lt;br /&gt;
* Так как хеш-функция хорошая, то в цепочке только полезные данные&lt;br /&gt;
* Если цепочка длинная, значит этому набору столбцов соответствует много строк, значит база данных так и задумывалась.&lt;br /&gt;
&lt;br /&gt;
При этом получаем&lt;br /&gt;
* Линейное время поиска&lt;br /&gt;
* В случае, если данных много, мы не можем просто увеличить число корзин и перенести данные, так как перехешировать таблицу очень долго&lt;br /&gt;
&lt;br /&gt;
[[Файл:Index_Hash_Sequence.png|мини|Цепочки страниц]]&lt;br /&gt;
&lt;br /&gt;
=== Расширяемое хеширование ===&lt;br /&gt;
&lt;br /&gt;
* Большое количество корзин, сильно больше чем требуется&lt;br /&gt;
* Несколько корзин на одной странице, чтобы не аллоцировать для каждой корзины страницу&lt;br /&gt;
** Обычно - последовательных&lt;br /&gt;
** Разделение корзин при переполнении страницы&lt;br /&gt;
* Не работает при плохой хеш-функции, но у нас хорошая&lt;br /&gt;
&lt;br /&gt;
При переполнении страницы мы:&lt;br /&gt;
* разделяем ее на несколько страниц&lt;br /&gt;
* разделим страницы, которые на нее ссылались, на несколько групп&lt;br /&gt;
* Каждой такой группе выделим по странице&lt;br /&gt;
&lt;br /&gt;
Стоимость: $1$ чтение и запись стольких страниц, на сколько мы разделили (обычно $2$)&lt;br /&gt;
&lt;br /&gt;
[[Файл:Index_Hash_Extendable.png|мини|Расширяемое хеширование]]&lt;br /&gt;
&lt;br /&gt;
=== Побитное расширяемое хеширование ===&lt;br /&gt;
&lt;br /&gt;
*Глубина хеша $n$&lt;br /&gt;
** Создадим $2^n$ корзин&lt;br /&gt;
* Для каждой страницы хранится ее локальная глубина $k$&lt;br /&gt;
** Это значит что она хранит $2^{n−k}$ последовательных корзин на странице&lt;br /&gt;
** Может быть разной для разных страниц&lt;br /&gt;
* При переполнении происходит разделение корзин&lt;br /&gt;
** Страница глубины $k$ разделяется на две глубины $k+1$&lt;br /&gt;
&lt;br /&gt;
=== Ускоряемые запросы ===&lt;br /&gt;
&lt;br /&gt;
*Проверка существования ключа&lt;br /&gt;
**Проверка повторений (ключи)&lt;br /&gt;
**''in'' - только если есть все необходимые атрибуты&lt;br /&gt;
**''exist'' - только если есть все необходимые атрибуты&lt;br /&gt;
**''count'' - зачастую можно посчитать по индексу count, не обращаясь к самим записям&lt;br /&gt;
*Поиск по ключу&lt;br /&gt;
**Естественные соединения&lt;br /&gt;
&lt;br /&gt;
== Упорядоченные индексы ==&lt;br /&gt;
&lt;br /&gt;
Традиционно реализуются на деревьях поиска&lt;br /&gt;
&lt;br /&gt;
* Предварительная обработка&lt;br /&gt;
** Ключи упорядочиваются по возрастанию - так как ключ составной, то используем лексикографисечкое возрастание&lt;br /&gt;
* Поиск в индексе&lt;br /&gt;
** Поиск в упорядоченной последовательности&lt;br /&gt;
&lt;br /&gt;
Деревья поиска&lt;br /&gt;
* Количество операций&lt;br /&gt;
** Обычно пропорционально $O$(высоты)&lt;br /&gt;
** Так как время выполнение операций зависит от высоты, для оптимизации времени нужно минимизировать высоту&lt;br /&gt;
* Размер узла&lt;br /&gt;
** Хотим эффективно использовать страницы&lt;br /&gt;
** Сильно ветвящиеся деревья, так размер узла будет ~странице и высота будет минимальной&lt;br /&gt;
&lt;br /&gt;
=== $B$ и $B+$ деревья ===&lt;br /&gt;
&lt;br /&gt;
* $B$ деревья степени $n$&lt;br /&gt;
** От $\frac{n}{2}$ до n детей&lt;br /&gt;
** Указатели и ключи хранятся в узлах&lt;br /&gt;
* $B+$ деревья степени $n$&lt;br /&gt;
** От $\frac{n}{2}$ до $n$ детей&lt;br /&gt;
** Указатели хранятся в листьях&lt;br /&gt;
&lt;br /&gt;
* $B+$ меньше данных в узлах - сильнее ветвятся&lt;br /&gt;
* $B+$ на одну страницу глубже&lt;br /&gt;
&lt;br /&gt;
Мы храним корень и несколько первых уровней в памяти для быстрого обращения, из-за этого время работы может резко возрастать, когда заканчивается закешированные уровни.&lt;br /&gt;
&lt;br /&gt;
=== Плотные и разряженные индексы ===&lt;br /&gt;
&lt;br /&gt;
* Плотный индекс&lt;br /&gt;
** Храним ключи всех элементов&lt;br /&gt;
* Разряженные индекс&lt;br /&gt;
** Храним ключи части элементов&lt;br /&gt;
** Обычно – один на страницу, мы можем найти данные в рамках этой страницы без загрузки новых&lt;br /&gt;
** Разряженный индекс бычно используется для кластеризованных индексов&lt;br /&gt;
** Уменьшает число уровней&lt;br /&gt;
&lt;br /&gt;
Так как упорядоченных индекс хранит сами данные в узлах, а не только хеш, то чем больше индексируеммые данные, тем меньше степень ветвления&lt;br /&gt;
&lt;br /&gt;
*Строки&lt;br /&gt;
**Много данных в ключе – меньше степень ветвления&lt;br /&gt;
**Можно использовать префиксы&lt;br /&gt;
**Строки опасно использовать в качестве индекса, может сильно вырости высота дерева&lt;br /&gt;
*Суррогатные ключи&lt;br /&gt;
**Малый размер&lt;br /&gt;
**Выше эффективность&lt;br /&gt;
**Широкие и низкие деревья - хорошо&lt;br /&gt;
*Изменяющиеся данные&lt;br /&gt;
**Частое обновление индекса&lt;br /&gt;
**Уменьшение индекса&lt;br /&gt;
**Не эффективно, для уменьшения данных нужна отдельная таска&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ускоряемые запросы ===&lt;br /&gt;
* Проверка существования ключа&lt;br /&gt;
* Поиск по ключу&lt;br /&gt;
* Минимум и максимум среди значений, на которых построен ключ&lt;br /&gt;
* Диапазон &lt;br /&gt;
** Загрузка&lt;br /&gt;
** count. count * работает быстроее, так как не нужно идти по всем данным&lt;br /&gt;
* Если построен на строках, like по префиксу&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;br /&gt;
* ''Дейт К. Введение в системы баз данных (Приложение Г)''&lt;br /&gt;
* ''Кнут Д. Искусство программирования. Том 3. Сортировка и поиск''&lt;br /&gt;
* ''Silberschatz A., Korth H. F., Sudarshan S. Database System Concepts''&lt;br /&gt;
&lt;br /&gt;
[[Категория: Базы данных]]&lt;/div&gt;</summary>
		<author><name>91.143.51.202</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D0%B0%D1%86%D0%B8%D1%8F_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85._%D0%A3%D0%BF%D0%BE%D1%80%D1%8F%D0%B4%D0%BE%D1%87%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5_%D0%B8_%D1%85%D0%B5%D1%88-%D0%B8%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D1%8B&amp;diff=82014</id>
		<title>Индексация данных. Упорядоченные и хеш-индексы</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D0%B0%D1%86%D0%B8%D1%8F_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85._%D0%A3%D0%BF%D0%BE%D1%80%D1%8F%D0%B4%D0%BE%D1%87%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5_%D0%B8_%D1%85%D0%B5%D1%88-%D0%B8%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D1%8B&amp;diff=82014"/>
				<updated>2021-12-27T09:08:30Z</updated>
		
		<summary type="html">&lt;p&gt;91.143.51.202: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Индексы ==&lt;br /&gt;
&lt;br /&gt;
Индексы нужны для того, чтобы оптимально искать нужные записи в таблице.&lt;br /&gt;
&lt;br /&gt;
Всего есть два способа найти нужные данные:&lt;br /&gt;
* Полный просмотр таблицы&lt;br /&gt;
** Последовательный перебор записей&lt;br /&gt;
** Быстро работает на маленьких таблицах, но медленно на средних и больших&lt;br /&gt;
** Если выбираем большую часть данных, то работает быстро. Иначе - медленно&lt;br /&gt;
* Индекс&lt;br /&gt;
** Произвольный набор столбцов&lt;br /&gt;
** Требуется предварительная обработка таблицы как при построении, так и при обновлении&lt;br /&gt;
** Быстрый поиск в индексе, сразу получаем указатель на запись&lt;br /&gt;
&lt;br /&gt;
На больших данных вся таблица не помещяется в память, из-за этого время работы очень сильно возрастает. &lt;br /&gt;
&lt;br /&gt;
Из-за всего вышеперечисленного, на больших данных использование полного просмотра становится на практике неприемлимым и используется индексация. На маленьких данных полный перебор работает хорошо и неб проблем может применяться на практике.&lt;br /&gt;
&lt;br /&gt;
=== Кластеризованный индекс ===&lt;br /&gt;
&lt;br /&gt;
[[Файл:Index_Clustered.png|мини|Кластеризованный индекс]]&lt;br /&gt;
&lt;br /&gt;
Если данные в таблице хранятся в порядке индекса, то такой индекс называется '''кластеризованным'''. Кластеризованный индекс позволяет увеличить скорость просмотра, однако так хранить данные возможно только если в таблице есть всего один индекс.&lt;br /&gt;
&lt;br /&gt;
=== Структура Индекса ===&lt;br /&gt;
&lt;br /&gt;
[[Файл:Index_Structure.png|мини|Структура индекса]]&lt;br /&gt;
&lt;br /&gt;
В общем случае индексы хранят отображение из ключей на идентификаторы записей, которые ведут на записи, которые мы загружаем&lt;br /&gt;
&lt;br /&gt;
Есть два подхода к реализации индексов: &lt;br /&gt;
* Хеш-таблицы&lt;br /&gt;
* Деревья поиска&lt;br /&gt;
&lt;br /&gt;
== Хеш-индексы == &lt;br /&gt;
* Предварительная обработка&lt;br /&gt;
** Подсчет хешей ключей. Хеш-функция задается разработчиком СУБД, что дает нам гарантии хорошего статистического распределения.&lt;br /&gt;
** Разбиение на корзины&lt;br /&gt;
* Поиск в индексе&lt;br /&gt;
** Просмотр корзины&lt;br /&gt;
** Несколько ключей в корзине. Коллизии могут быть, так как индекс не всегда ключ.&lt;br /&gt;
* Заголовок помещяется в памяти&lt;br /&gt;
[[Файл:Index_Hash_Simple.png|мини|Простой хеш-индекс]]&lt;br /&gt;
&lt;br /&gt;
Однако может наступить момент, когда очередная корзина не помещается в страницу, в таком случае мы так же храним их цепочками. &lt;br /&gt;
&lt;br /&gt;
* Так как хеш-функция хорошая, то в цепочке только полезные данные&lt;br /&gt;
* Если цепочка длинная, значит этому набору столбцов соответствует много строк, значит база данных так и задумывалась.&lt;br /&gt;
&lt;br /&gt;
При этом получаем&lt;br /&gt;
* Линейное время поиска&lt;br /&gt;
* В случае, если данных много, мы не можем просто увеличить число корзин и перенести данные, так как перехешировать таблицу очень долго&lt;br /&gt;
&lt;br /&gt;
[[Файл:Index_Hash_Sequence.png|мини|Цепочки страниц]]&lt;br /&gt;
&lt;br /&gt;
=== Расширяемое хеширование ===&lt;br /&gt;
&lt;br /&gt;
* Большое количество корзин, сильно больше чем требуется&lt;br /&gt;
* Несколько корзин на одной странице, чтобы не аллоцировать для каждой корзины страницу&lt;br /&gt;
** Обычно - последовательных&lt;br /&gt;
** Разделение корзин при переполнении страницы&lt;br /&gt;
* Не работает при плохой хеш-функции, но у нас хорошая&lt;br /&gt;
&lt;br /&gt;
При переполнении страницы мы:&lt;br /&gt;
* разделяем ее на несколько страниц&lt;br /&gt;
* разделим страницы, которые на нее ссылались, на несколько групп&lt;br /&gt;
* Каждой такой группе выделим по странице&lt;br /&gt;
&lt;br /&gt;
Стоимость: $1$ чтение и запись стольких страниц, на сколько мы разделили (обычно $2$)&lt;br /&gt;
&lt;br /&gt;
[[Файл:Index_Hash_Extendable.png|мини|Расширяемое хеширование]]&lt;br /&gt;
&lt;br /&gt;
=== Побитное расширяемое хеширование ===&lt;br /&gt;
&lt;br /&gt;
*Глубина хеша $n$&lt;br /&gt;
** Создадим $2^n$ корзин&lt;br /&gt;
* Для каждой страницы хранится ее локальная глубина $k$&lt;br /&gt;
** Это значит что она хранит $2^{n−k}$ последовательных корзин на странице&lt;br /&gt;
** Может быть разной для разных страниц&lt;br /&gt;
* При переполнении происходит разделение корзин&lt;br /&gt;
** Страница глубины $k$ разделяется на две глубины $k+1$&lt;br /&gt;
&lt;br /&gt;
=== Ускоряемые запросы ===&lt;br /&gt;
&lt;br /&gt;
*Проверка существования ключа&lt;br /&gt;
**Проверка повторений (ключи)&lt;br /&gt;
**''in'' - только если есть все необходимые атрибуты&lt;br /&gt;
**''exist'' - только если есть все необходимые атрибуты&lt;br /&gt;
**''count'' - зачастую можно посчитать по индексу count, не обращаясь к самим записям&lt;br /&gt;
*Поиск по ключу&lt;br /&gt;
**Естественные соединения&lt;br /&gt;
&lt;br /&gt;
== Упорядоченные индексы ==&lt;br /&gt;
&lt;br /&gt;
Традиционно реализуются на деревьях поиска&lt;br /&gt;
&lt;br /&gt;
* Предварительная обработка&lt;br /&gt;
** Ключи упорядочиваются по возрастанию - так как ключ составной, то используем лексикографисечкое возрастание&lt;br /&gt;
* Поиск в индексе&lt;br /&gt;
** Поиск в упорядоченной последовательности&lt;br /&gt;
&lt;br /&gt;
Деревья поиска&lt;br /&gt;
* Количество операций&lt;br /&gt;
** Обычно пропорционально $O$(высоты)&lt;br /&gt;
** Так как время выполнение операций зависит от высоты, для оптимизации времени нужно минимизировать высоту&lt;br /&gt;
* Размер узла&lt;br /&gt;
** Хотим эффективно использовать страницы&lt;br /&gt;
** Сильно ветвящиеся деревья, так размер узла будет ~странице и высота будет минимальной&lt;br /&gt;
&lt;br /&gt;
=== $B$ и $B+$ деревья ===&lt;br /&gt;
&lt;br /&gt;
* $B$ деревья степени $n$&lt;br /&gt;
** От $\frac{n}{2}$ до n детей&lt;br /&gt;
** Указатели и ключи хранятся в узлах&lt;br /&gt;
* $B+$ деревья степени $n$&lt;br /&gt;
** От $\frac{n}{2}$ до $n$ детей&lt;br /&gt;
** Указатели хранятся в листьях&lt;br /&gt;
&lt;br /&gt;
* $B+$ меньше данных в узлах - сильнее ветвятся&lt;br /&gt;
* $B+$ на одну страницу глубже&lt;br /&gt;
&lt;br /&gt;
Мы храним корень и несколько первых уровней в памяти для быстрого обращения, из-за этого время работы может резко возрастать, когда заканчивается закешированные уровни.&lt;br /&gt;
&lt;br /&gt;
=== Плотные и разряженные индексы ===&lt;br /&gt;
&lt;br /&gt;
* Плотный индекс&lt;br /&gt;
** Храним ключи всех элементов&lt;br /&gt;
* Разряженные индекс&lt;br /&gt;
** Храним ключи части элементов&lt;br /&gt;
** Обычно – один на страницу, мы можем найти данные в рамках этой страницы без загрузки новых&lt;br /&gt;
** Разряженный индекс бычно используется для кластеризованных индексов&lt;br /&gt;
** Уменьшает число уровней&lt;br /&gt;
&lt;br /&gt;
Так как упорядоченных индекс хранит сами данные в узлах, а не только хеш, то чем больше индексируеммые данные, тем меньше степень ветвления&lt;br /&gt;
&lt;br /&gt;
*Строки&lt;br /&gt;
**Много данных в ключе – меньше степень ветвления&lt;br /&gt;
**Можно использовать префиксы&lt;br /&gt;
**Строки опасно использовать в качестве индекса, может сильно вырости высота дерева&lt;br /&gt;
*Суррогатные ключи&lt;br /&gt;
**Малый размер&lt;br /&gt;
**Выше эффективность&lt;br /&gt;
**Широкие и низкие деревья - хорошо&lt;br /&gt;
*Изменяющиеся данные&lt;br /&gt;
**Частое обновление индекса&lt;br /&gt;
**Уменьшение индекса&lt;br /&gt;
**Не эффективно, для уменьшения данных нужна отдельная таска&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ускоряемые запросы ===&lt;br /&gt;
* Проверка существования ключа&lt;br /&gt;
* Поиск по ключу&lt;br /&gt;
* Минимум и максимум среди значений, на которых построен ключ&lt;br /&gt;
* Диапазон &lt;br /&gt;
** Загрузка&lt;br /&gt;
** count. count * работает быстроее, так как не нужно идти по всем данным&lt;br /&gt;
* Если построен на строках, like по префиксу&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;br /&gt;
* ''Дейт К. Введение в системы баз данных (Приложение Г)''&lt;br /&gt;
* ''Кнут Д. Искусство программирования. Том 3. Сортировка и поиск''&lt;br /&gt;
* ''Silberschatz A., Korth H. F., Sudarshan S. Database System Concepts''&lt;br /&gt;
&lt;br /&gt;
[[Категория: Базы данных]]&lt;/div&gt;</summary>
		<author><name>91.143.51.202</name></author>	</entry>

	</feed>