Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Организация хранения данных в СУБД

350
20 июня 2006 года
cheburator
589 / / 01.06.2006
Предисловие к вопросу.
Таблицы, имеющие первичный ключ, могут организовываться в кластер, т. е. все строки, соответствующие узлу B-дерева индекса, образуют единый блок, или кластер. Поскольку ключ первичный, подразумевается, что при поиске данных в таблице чаще всего будет использоваться именно он, т. е. будут использоваться условия типа WHERE ПолеПервичногоКлюча Больше-Меньше-Равно-и-т-д КакоеТоУсловие, поэтому поэтому при получении строк в таком запросе получаемые строки с большой вероятностью будут находится "рядом" друг с другом, в одном кластере, т. е. одним чтением из файла БД мы скорее всего прочитаем большое количество строк, соответствующих нашему условию. Получаем очевидное ускорение работы по сравнению с некластерно-организованной таблицей, где строки "разбросаны" и приходится делать много подгрузок из файла БД. К тому же кластер будет скорее всего представлять собой массив, а не связный список, поэтому доступ к элементам будет произвольный, что также ускоряет работу.
Как видим, таблица, имеющая первичный ключ, может быть кластерно-организованной.
Но в большинстве СУБД для всех (!) таблиц используется блочная (экстентная) организация таблиц.
СОБСТВЕННО ВОПРОС
Почему? Какие преимущества дает блочная (экстентная) организация?
Ведь если я кучу строк организую в единый блок, какую оптимизацию это даст, если это - просто сваленные в кучу строки, не имеющие, скорее всего, между собой ничего общего. Чем хуже, если я "раскидаю" строки по всему файлу БД?
Второй вопрос: зачем нужны табличные пространства? Опять же, я могу раскидать данные по всей БД.

P. S.
Вышеуказанный вопрос задается в связи с тем, что вся эта организация и внутренняя структура хорошо описана во многих книгах, но, к сожалению, вряд ли указаны причины именно такой организации. Я, често говоря, не очень искал, но не думаю, что это можно найти в какой-либо литературе. Просто хочу услышать ваши соображения.
10
20 июня 2006 года
Freeman
3.2K / / 06.03.2004
[QUOTE=cheburator]Как видим, таблица, имеющая первичный ключ, может быть кластерно-организованной.[/QUOTE]
Не припоминаю в Oracle понятие кластера. Это из MS SQL взято?

[QUOTE=cheburator]Но в большинстве СУБД для всех (!) таблиц используется блочная (экстентная) организация таблиц.[/QUOTE]
Блоки и экстенты - разные уровни, смешивать их нельзя.

[QUOTE=cheburator]Почему? Какие преимущества дает блочная (экстентная) организация?[/QUOTE]
Блочная - никаких преимуществ не дает, это следствие линейности используемых носителей. Экстентная - способ обойти линейность на более высоком уровне инкапсуляции.

[QUOTE=cheburator]Ведь если я кучу строк организую в единый блок, какую оптимизацию это даст, если это - просто сваленные в кучу строки, не имеющие, скорее всего, между собой ничего общего.[/QUOTE]
В Oracle чаще всего используются таблицы, организованные в куче и организованные по индексу. Второй тип подходит под твое "кластерное" описание.

В реляционной модели физическая последовательность записей в таблице не определена. Логическая же для таблиц по куче также не определена, а для организованных по индексу определяется первичным ключом.

[QUOTE=cheburator]Чем хуже, если я "раскидаю" строки по всему файлу БД?[/QUOTE]
Каким образом?

[QUOTE=cheburator]Второй вопрос: зачем нужны табличные пространства? Опять же, я могу раскидать данные по всей БД.[/QUOTE]
Уже отвечал. БД по определению никак не связана с аппаратными устройствами. Табличные пространства - способ установить связь на логическом уровне. Из всех СУБД, по-моему, они только в Oracle присутствуют.
2
20 июня 2006 года
squirL
5.6K / / 13.08.2003
[quote=Freeman]Не припоминаю в Oracle понятие кластера. Это из MS SQL взято?
[/quote]

неа. есть такое и в Oracle.
350
22 июня 2006 года
cheburator
589 / / 01.06.2006
Спасибо за ответ, но он не совсем понятен. Например:
[QUOTE=Freeman]Блочная - никаких преимуществ не дает, это следствие линейности используемых носителей. Экстентная - способ обойти линейность на более высоком уровне инкапсуляции.[/QUOTE]
- о какой линейности идет речь и причем тут инкапсуляция?

[QUOTE=Freeman]Cheburator: Чем хуже, если я "раскидаю" строки по всему файлу БД?
Freeman: Каким образом?[/QUOTE]
Объясняю. Знаешь, что такое куча в оперативной памяти? Это когда при очередном запросе блока памяти выделяется первый попавшийся свободный блок подходящего размера. Так же и в этом случае: ищем первый попавшийся блок в файле БД и выделяем его для очередной строки. Таким образом, файл БД фрагментируется (точнее, каждая отдельно взятая таблица), ее строки "раскиданы" по всему файлу.
Блочная же организация, я так понимаю, работает так: место в файле выделяется большими блоками, рассчитанными на хранение большого количества строк. Как только блок заполняется, выделяется еще один и т. д. Но смысл?
Насчет твоей ссылки, где ты писал:
[QUOTE=Freeman]Файлы могут храниться на разных устройствах SCSI, например. При правильной организации хранения запросы на чтение, скажем, блоков индексов и блоков таблиц будут выполняться параллельно.[/QUOTE]
Как они выполняются параллельно, если для того, чтобы прочитать данные из таблицы, нужно их сначала найти по индексу? Т. е. сначала считывается индекс, находятся нужные строки, затем уж считываются строки из таблицы. Насколько я понимаю.
10
22 июня 2006 года
Freeman
3.2K / / 06.03.2004
[QUOTE=cheburator]- о какой линейности идет речь и причем тут инкапсуляция?[/QUOTE]
Я про Seek в потоке. Поток линеен. Для удобства его делят на блоки, но размер блока диктуется эффективностью работы аппаратных средств. Экстент же - логическая единица, выбираемая по прикладной потребности.

[QUOTE=cheburator]Блочная же организация, я так понимаю, работает так: место в файле выделяется большими блоками, рассчитанными на хранение большого количества строк. Как только блок заполняется, выделяется еще один и т. д. Но смысл?[/QUOTE]
Базы разные нужны, базы разные важны. Не приходилось видеть базу из нескольких сотен, или (боже упаси!) тысяч таблиц? Можешь прикинуть, какой там разброс будет? Часть таблиц - справочники, небольшого размера и практически неизменяемые. А нечто вроде "Главной книги проводок" - невъе..нного размера, плюс каждый день растет.

Много возможностей в СУБД реализовано "на вырост". С данными шутки плохи, и неизвестно, что завтра понадобится при решении задачи. Не будешь же каждый раз ядро переписывать. Тем более, что там сплошная математика - заплаты не прокатят.

Элементарно, чтобы при экспорте/импорте, когда размер таблиц уже известен, выделить сразу экстент нужного размера, соответствующая возможность должна быть предусмотрена ядром. А если есть реализация, почему бы ее пользователю не вынести? Мы же не Майкрософт, чтобы полезные фишки прятать.

[QUOTE=cheburator]Т. е. сначала считывается индекс, находятся нужные строки, затем уж считываются строки из таблицы. Насколько я понимаю.[/QUOTE]
Ты вообще представляешь, как выполняется запрос? Вначале строится план, дается на съедение оптимизатору, и только потом начинается непосредственно выборка.

Курсоры - по определению однонаправлены. Не выбрав курсор полностью, нельзя узнать число записей в нем. Соответственно, пока пользователь пялится на первые 25 строк на экране, СУБД может продолжать выборку. Не забывай про реляционную алгебру, занимающую большую часть выполнения запроса.
350
24 июня 2006 года
cheburator
589 / / 01.06.2006
[QUOTE=Freeman]Базы разные нужны, базы разные важны. Не приходилось видеть базу из нескольких сотен, или (боже упаси!) тысяч таблиц? Можешь прикинуть, какой там разброс будет? Часть таблиц - справочники, небольшого размера и практически неизменяемые. А нечто вроде "Главной книги проводок" - невъе..нного размера, плюс каждый день растет.
Много возможностей в СУБД реализовано "на вырост". С данными шутки плохи, и неизвестно, что завтра понадобится при решении задачи. Не будешь же каждый раз ядро переписывать. Тем более, что там сплошная математика - заплаты не прокатят.

Элементарно, чтобы при экспорте/импорте, когда размер таблиц уже известен, выделить сразу экстент нужного размера, соответствующая возможность должна быть предусмотрена ядром. А если есть реализация, почему бы ее пользователю не вынести? Мы же не Майкрософт, чтобы полезные фишки прятать.[/QUOTE]
Видел я многие сотни таблиц, каждый день с ними работаю (например, Управление производственным предприятием 1С v 8.0).
А как такая идея: файл (или файлы) данных условно бьются на страницы (размером, скажем, по 2 Мб), отображаются на память при работе с таблицей целыми окнами. Внутри каждого окна ведется свой собственный список свободной памяти (индексирован по размеру блока и по стартовому адресу). Получается, своего рода "вырост" базы данных (в целом, а не каждой таблицы отдельно) - 2 Мб. Как только требуется место (неважно, для какой таблицы) - выделяется место или в существующей странице, если место там есть, или выделяется новая страница. В общем, суть первоначального вопроса этой темы: зачем выделять отдельные экстенты каждой таблице? Зачем каждую отдельно вести "навырост"? Вести всю БД - чем плохо? Те же справочники, которые редко меняются - ну пусть редко меняются, а если часто создаются/удаляются проводки - пусть часто создаются или удаляются, зачем выводить это на уровень таблицы, если можно вести на уровне БД в целом? Я подумал, что причина тут - не просто "вырост", а преследуется какая-то оптимизационная цель, типа как в кластерах. Видимо, нет. А раз оптимальности это никакой не дает, тем более, повторюсь, зачем выделять аспект "выроста" на уровень таблицы - можно выделять пространство большими блоками на уровне БД в целом, а уж строки какой таблицы туда попадут - дело случая.
[QUOTE=Freeman]
Ты вообще представляешь, как выполняется запрос? Вначале строится план, дается на съедение оптимизатору, и только потом начинается непосредственно выборка.[/QUOTE]
Вот запрос: SELECT * FROM goods WHERE price <= 500, причем price - поле индексированное. Я так понимаю, чтобы система исполнения запросов вообще узнала, какие строки нужно "вытащить" из таблицы, нужно вначале обратиться к индексу, найдя в нем идентификаторы/ссылки/или-что-там-еще этих самых строк. Т. е. выходит, что в любом случае читаем индекс, обрабатываем (ищем в нем), затем читаем собственно строки из таблицы. Какой бы план ни был. А уж какой индекс и как искать - вот это уже дело плана и оптимизатора. Выходит, не совсем понятно, как же так можно читать строки таблицы и индекс одновременно. Если только блоками - нашли первые 500 строк с помощью индекса - создаем параллельный поток, даем ему задание прочесть эти строки, сами в это время ищем следующий блок строк и т. д.
10
24 июня 2006 года
Freeman
3.2K / / 06.03.2004
[QUOTE=cheburator]А как такая идея: файл (или файлы) данных условно бьются на страницы (размером, скажем, по 2 Мб), отображаются на память при работе с таблицей целыми окнами.[/QUOTE]
Ты опять-таки мыслишь чисто системно, чего в проектировании делать нельзя - получается системность ради системности.

[QUOTE=cheburator]В общем, суть первоначального вопроса этой темы: зачем выделять отдельные экстенты каждой таблице? Зачем каждую отдельно вести "навырост"?[/QUOTE]
Так можно вести и не навырост. Если точно известно, что размер справочника статичен, можно задать увеличение в 0. Суть в том, что прикладные программисты намного лучше понимают поведение той или иной таблицы, и у них должны быть средства, чтобы это поведение описать.

[QUOTE=cheburator]Я подумал, что причина тут - не просто "вырост", а преследуется какая-то оптимизационная цель, типа как в кластерах.[/QUOTE]
А она и есть. Понять ее - было твоим домашним заданием.

[QUOTE=cheburator]А раз оптимальности это никакой не дает, тем более, повторюсь, зачем выделять аспект "выроста" на уровень таблицы - можно выделять пространство большими блоками на уровне БД в целом, а уж строки какой таблицы туда попадут - дело случая.[/QUOTE]
Если исходить из парадигмы одного файла - согласен. Если из табличных пространств - нет. Впрочем, чисто статичные справочники могут быть и там, и там.

[QUOTE=cheburator]Т. е. выходит, что в любом случае читаем индекс, обрабатываем (ищем в нем), затем читаем собственно строки из таблицы. Какой бы план ни был.[/QUOTE]
Угу. Вот тут-то и надо проявить системное мышление. Создается поток поиска по индексу и поток выборки данных, организуется между ними канал. Продолжать?

К тому же, пример слишком простой, поэтому распараллеливание именно его может оказаться стрельбой из пушки по воробьям. Если же к выборке добавится несколько связываний - уже нет.
350
27 июня 2006 года
cheburator
589 / / 01.06.2006
Мда... Скажу только одно.
[QUOTE=Freeman]А она и есть. Понять ее - было твоим домашним заданием.[/QUOTE]
Это не мое домашнее задание. Это мой первоначальный вопрос. Четкого и ясного ответа, к сожалению, я не услышал.
А если я мышлю не системно (блоки/экстенты), то виноват в этом пресловутый Кайт.
1
27 июня 2006 года
kot_
7.3K / / 20.01.2000
[QUOTE=Freeman]
Не припоминаю в Oracle понятие кластера. Это из MS SQL взято?
...

Табличные пространства - способ установить связь на логическом уровне. Из всех СУБД, по-моему, они только в Oracle присутствуют.[/QUOTE]
Первое в оракле присутствует, второе есть не только в нем :)
А по сути заданного вопроса - на него достаточно подробный ответ дает Кен Хендерсон в книге "Профессиональное руководство по SQL Server. Структура и реализация".

З.Ы. Читая Кайта.
"Армяне лучше чем грузины. Чем лучше? Чем грузины!!!" иногда вспоминается :)
350
28 июня 2006 года
cheburator
589 / / 01.06.2006
При экстентной организации данных не нужно дерево свободной памяти, которое пришлось бы использовать при "страничной" организации, описанной мною выше. В экстенте все "ячейки" - одинакового размера (место ровно для одной строки), что напоминает low-fragmentation heap, и не нужно держать дерево свободной памяти страницы - достаточно простой список. При выделении места для очередной строки тупо берем первый элемент списка - т. е. не нужно искать по дереву свободной памяти элемент достаточного размера. Освобождение места при удалении строки также будет работать быстрее (за счет того, что не придется производить изменения в том же дереве свободной памяти). К тому же, экстенту будут присущи все свойства малофрагментируемой кучи.
Больше преимуществ не вижу.
Вот такие примерно мои рассуждения. Что-то в этом роде я ожидал услышать. Ну что ж, все приходится делать самому :) :(
19K
28 июня 2006 года
pasha_pasha
2 / / 28.06.2006
Вот например:
[QUOTE=cheburator]Таблицы, имеющие первичный ключ, могут организовываться в кластер, т. е. все строки, соответствующие узлу B-дерева индекса, образуют единый блок, или кластер. [/QUOTE]
В кластер (имеется в виду тип сегмента "кластер" БД Oracle - с терминами других БД я не знаком) имеет смысл организовывать таблицы, которые в большинстве случаев используются совместно - этакая денормализация.
То что имелось в виду в вопросе - скорее всего Table Partition (с некоторым натягом). Но для Table Partition нужно определить по какому принципу мы организовываем хранение данных -например данные за 2005 год-в этой партиции, за 2006 - вот в этой.
[QUOTE=cheburator]Как видим, таблица, имеющая первичный ключ, может быть кластерно-организованной.[/QUOTE] Все таблицы могут иметь первичный ключ, однако не все можно организовать в Partition Table (точнеее не все - целесообразно)
[QUOTE=cheburator]К тому же кластер будет скорее всего представлять собой массив, а не связный список, поэтому доступ к элементам будет произвольный, что также ускоряет работу.
[/QUOTE]
А что Вы называете "связным списком"?
[QUOTE=cheburator]Но в большинстве СУБД для всех (!) таблиц используется блочная (экстентная) организация таблиц[/QUOTE]
Блочная организация, на мой взгляд, обусловлена:
1. Блочной организацией носителей данных
2. Необходимостью адресации записи данных в массиве
19K
28 июня 2006 года
pasha_pasha
2 / / 28.06.2006
[QUOTE=cheburator]При экстентной организации данных не нужно дерево свободной памяти, которое пришлось бы использовать при "страничной" организации, описанной мною выше. В экстенте все "ячейки" - одинакового размера (место ровно для одной строки), что напоминает low-fragmentation heap, и не нужно держать дерево свободной памяти страницы - достаточно простой список. При выделении места для очередной строки тупо берем первый элемент списка - т. е. не нужно искать по дереву свободной памяти элемент достаточного размера. Освобождение места при удалении строки также будет работать быстрее (за счет того, что не придется производить изменения в том же дереве свободной памяти). К тому же, экстенту будут присущи все свойства малофрагментируемой кучи.
Больше преимуществ не вижу.[/QUOTE]
Откуда взялась идея, что мы знаем размер строки и этот размер всегда одинаков?
Описаный алгоритм "страничной" организации в-общем то очень похож на существующие - просто разные его части работают на разных уровнях и оперируют разными объектами - блоками, экстентами, строками таблиц и т.п. А идея выделять место для записей различных таблиц (страницу) - не выдерживает никакой критики. (на мой взгляд)
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог