Стоит ли ЭТО делать с помощью Реляционных БД?
От: vl690001x Россия  
Дата: 03.08.09 16:23
Оценка: +1
Вопрос к специалистам...
В общем, с программированием я связан давно, но с большими перерывами. Немножко программировал на Delphi, хотел перейти на С++, но прочитав на этом сайте статью .NET vs С++, где-то с полгода уже изучаю С#, правда тоже с перерывами, но все же успехи есть.
Может быть, это длинное вступление и ни к чему, но изучаю я С# это в общем, с определенной целью — написать программу — телефонный справочник. Дело в том, что имеющийся в наличии телефонный справочник г. Владивостока, содержащий около 4 миллионов телефонных номеров, поразил меня своей неэффективностью. Сейчас, получив некоторые смутные представления о реляционных БД, я понимаю, что архитектура его крайне неэффективна — все данные содержатся в одной-единственной таблице с несколькими полями: телефон, ФИО, улица, дом, квартира. Еще год назад, не зная о теории БД ничего, я придумал способ оптимизации — во первых, разделить ФИО на 3 отдельных поля, во-вторых, устранить дублирование инфрормации. Основная цель всего этого — уменьшить размер БД (около гигобайта в первоночальном варианте файла mdb), и увеличить скорость поиска до максимума по всем полям, а не только по отсортированному. Где-то с месяц назад я начал делать движок своей собственной БД, и в принципе, он показывал неплохие результаты, но из-за большой сложности программы, и отсутствия опыта проектирования объектно-ориентированных приложений, мне пришлось приостановить этот процесс и засесть за изучение "Объектно-ориентированного анализа и проектирования" Гради Буча. За месяц я переписал его несколько раз, на каждой итерации приближаясь к желаемуому результату. Потом я открыл справку по Access, начал читать ее и подумал, что все что я открыл, уже давно придумано. Кроме того, я подумал, что C# — слишком высокоуровневый язык, и может быть, есть смысл не программировать на нем все на низком уровне, а использовать уже готовые сборки для этой цели. После непродолжительного поиска в гугле я пришел к выводу — что SQLite — это то что мне надо. Но все же, поскольку теорию реляционных БД я толком не изучал, меня гложат сомнения, можно ли будет осуществить мою задумку, то есть, сделать что-то аналогичное по эффективности задуманному мной движку БД. Архитектура его такая (если вкратце): Вся бд состоит из нескольких файлов. Есть файл "объектов", есть файл "вариантов", и есть файл "свойств". Каждый объект (в данном случае это просто человек) содержит некоторое количество свойств (например, фамилию, имя, отчество, номер телефона и т.д.). Он может и не содержать некоторых свойств, конечно. Какие именно свойства он содержит, указывается в придуманном мной понятии "вариант", проще говоря, это некое подмножество универсума свойств, которые может содержать объект. "Вариант" содержит ID-ы свойств, кроме того, в файле "вариантов" все они ("варианты") отсортированы по своим ID. Хотя, все еще проще — просто порядковый номер "варианта" и является его ID-ом, поскольку варианты добавляются последовательно, ID-ы уже имеющихся вариантов не меняются. В файле объектов хранятся объекты. То есть, собственно говоря, там хранятся последовательности: {ID варианта, ID 1-го ключа, .... , ID n-го ключа}. Каждый объект также имеет свой ID. Что касается ключей, то это экземпляры свойств объекта. Например, фамилии "Иванов", "Петров", "Сидоров" свойства "Фамилия". Каждый ключ имеет свой ID, для большинства свойств достаточно 2 байта, так как, например, навряд ли существует более 65536 всевозможных фамилий, то же самое можно сказать об улицах, именах и т.д, и лишь для номеров телефонов надо 4 байта. Таким образом, достигается экономия описания объектов в файле объектов. Зная ID объекта, мы читаем его "вариант", и узнаем, какие именно "свойства" он содержит, и какова длина ID каждого свойства, далее по очереди читаем ID-ы ключей этих свойств, и извлекаем сами ключи (то есть, фамилию, имя, отчество, номер телефона, и т.д.) из соответствующих файлов. Все просто, но конечно же, необходимо еще и обеспечить поиск по ключам. Тут все немножко сложнее, но тоже в принципе, достаточно красиво. Дело в том, что в файлах ключей хранятся списки ID объектов, которые имеют данный ключ. Конечно, такие списки могут быть достаточно длинны. Например, у ключа "Светланская" свойства "Улица" будет весьма внушительный список ID объектов, потому что улица большая, и народу в ней живет много. Но фишка в том, что все эти списки будут упорядочены по ID, и для этого не надо прикладывать доп. усилий, потому как объекты по идее будут добавляться в БД последовательно, и каждый будет иметь ID на единицу больше предыдущего. Таким образом, у свойств, которыми обладает этот объект, будет добавлен ID объекта, который гарантированно больше последнего. Сами же ключи могут быть упорядочены в алфавитном порядке (правда, это немножко сложней, хотя это я реализовал), но это не принципиально, все равно, ключей не так много, и они могут быть найдены почти мгновенно, за исключением номера телефона, потому разновидностей номеров телефонов как-раз то много. После того, как мы вводим запрос например, найти всех людей с фамилией Иванов и проживающих по улице Светланской, программа находит два списка объектов, и производит их слияние, создавая результирующий список, содержащий только те ID, которые есть в обоих списках. То же самое с запросами по любому количеству свойств. После чего узнать полную информацию об объектах просто. Конечно, тут непаханное поле для оптимизаций, но не будем вдаваться в подробности.
В общем, всем кто осилил это сумбурное послание, большое спасибо. Я очень хотел бы узнать, можно ли в реляционных БД создать что-то подобное по (предположительно высокой) скорости и гибкости. Разбить большую таблицу на маленькие по полям конечно просто, но как потом искать информацию по запросам, ведь в реляционных БД нельзя создать что-то подобное описанным мной "спискам объектов". Или может я ошибаюсь?
Заранее благодарю за ответы. В довершение хочу сказать, что описанная мной архитектура придумана мной, возможно, где-то такое уже есть, если кому что известно, пожалуйста, сообщите.
Re: Стоит ли ЭТО делать с помощью Реляционных БД?
От: Lloyd Россия  
Дата: 03.08.09 17:16
Оценка: 1 (1)
Здравствуйте, vl690001x, Вы писали:

V>В общем, всем кто осилил это сумбурное послание, большое спасибо. Я очень хотел бы узнать, можно ли в реляционных БД создать что-то подобное по (предположительно высокой) скорости и гибкости. Разбить большую таблицу на маленькие по полям конечно просто, но как потом искать информацию по запросам, ведь в реляционных БД нельзя создать что-то подобное описанным мной "спискам объектов". Или может я ошибаюсь?


Реляционные БД очень гибкий инструмент. Описанное вами вполне можно реализовать.
Re[2]: Стоит ли ЭТО делать с помощью Реляционных БД?
От: Donz Россия http://donz-ru.livejournal.com
Дата: 03.08.09 22:15
Оценка: +1 :)
Здравствуйте, Lloyd, Вы писали:

[offtop]
+1 стоит поставить хотя бы за то, что осилили столько букв
Re: Стоит ли ЭТО делать с помощью Реляционных БД?
От: Аноним  
Дата: 04.08.09 00:31
Оценка:
Если точнее, меня интересует такой вопрос. Если реляционная БД разбита на несколько таблиц, и, например, мы производим поиск например по 3-м полям (в 3-х таблицах): "имя", "отчество", "улица проживания", то какой механизм отображения всех записей главной таблицы, содержащих все три искомых ключа? Я так понимаю, для этого в этих трех таблицах должны быть обратные ссылки на списки записей основной таблицы? Если физически реляционные БД так и устроены, вопросов у меня больше нет. Но везде почему-то пишут о логике БД, а о том как это все устроено, я ничего не нашел.
Re: Стоит ли ЭТО делать с помощью Реляционных БД?
От: Ziaw Россия  
Дата: 04.08.09 05:21
Оценка:
Здравствуйте, vl690001x, Вы писали:

V>Заранее благодарю за ответы. В довершение хочу сказать, что описанная мной архитектура придумана мной, возможно, где-то такое уже есть, если кому что известно, пожалуйста, сообщите.


Реляционные СУБД очень быстро ищут все что нужно и сливают нужные списки. Наврядли вам удастся улучшить эти рузультаты. Что касается экономии места, оно обычно идет в ущерб производительности. Поэтому оптимальный вариант — выделите справочник улиц, а фамилию, имя, отчество, телефон, дом и квартиру оставьте в основной таблице. С помощью индексов поиск будет быстр настолько насколько это возможно.

Размер СУБД от "нормализации" фамилиий, имен и отчеств уменьшится нанамного.

Произвольный список атрибутов у каждого объекта, это овердизайн для данной задачи, ничего кроме тормозов и головной боли он вам не принесет. В принципе вы вполне можете попробовать реализовать данную схему, но не в реляционной СУБД. Для таких задач лучше подойдет что-то похожее на db4o.Net, по слухам она довольно быстра, если ее правильно готовить (сам не использовал).
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re: Стоит ли ЭТО делать с помощью Реляционных БД?
От: Sinix  
Дата: 04.08.09 06:12
Оценка: +1
Здравствуйте, vl690001x, Вы писали:

Можно но не особо нужно. Этот велосипед с незапамятных времён втюхивают... гуглить "схема Тенцера" (кстати Тенцер по этой теме окроме популяризаторских статей ничем не отметился, ну да фиг с ним) и модный нынче в облаках ака cloud'е EAV.

Идея конеш хорошая — получаем гибкую структуру — даже непрофессионалы могут накидать свою систему... Светлая мечта саппорта, так сказать...

На практике всё скатывается к эмуляции субд силами самой субд. Уж проще матчасть поизучать, честное слово... Кстати, эмулируется даже не РСУБД, а обычная "иерархическая модель данных" со всеми прелестями типа навигации по жёстким ссылкам, невозможности оптимизации и т.п... Кстати модная нынче тынденция, дерзайте — вдруг да попадёте в струю
Re: Стоит ли ЭТО делать с помощью Реляционных БД?
От: wildwind Россия  
Дата: 04.08.09 08:13
Оценка:
Здравствуйте, vl690001x, Вы писали:

V>разделить ФИО на 3 отдельных поля, во-вторых, устранить дублирование инфрормации. Основная цель всего этого — уменьшить размер БД (около гигобайта в первоночальном варианте файла mdb), и увеличить скорость поиска до максимума по всем полям, а не только по отсортированному.


Это — стоит.
Все остальное — нет. Реляционная СУБД не очень хорошо будет с этим справляться, особенно Access.

P. S. "Телефонный справочник" это не та задача, где подойдет модель EAV (то что вы описали), набор атрибутов тут фиксирован и меняется редко.
Re: Стоит ли ЭТО делать с помощью Реляционных БД?
От: Flying Dutchman Украина  
Дата: 04.08.09 08:39
Оценка: 4 (1)
Здравствуйте, vl690001x, Вы писали:

V>Вопрос к специалистам...

V>Может быть, это длинное вступление и ни к чему, но изучаю я С# это в общем, с определенной целью — написать программу — телефонный справочник. Дело в том, что имеющийся в наличии телефонный справочник г. Владивостока, содержащий около 4 миллионов телефонных номеров, поразил меня своей неэффективностью. Сейчас, получив некоторые смутные представления о реляционных БД, я понимаю, что архитектура его крайне неэффективна — все данные содержатся в одной-единственной таблице с несколькими полями: телефон, ФИО, улица, дом, квартира.

Да, это неправильно.

V>Еще год назад, не зная о теории БД ничего, я придумал способ оптимизации — во первых, разделить ФИО на 3 отдельных поля, во-вторых, устранить дублирование инфрормации.


Это называется "нормализация".

V>Основная цель всего этого — уменьшить размер БД (около гигобайта в первоночальном варианте файла mdb),


Это небольшой размер для современных баз данных. Не стоит экономить на спичках, лучше заняться разработкой правильной структуры БД.

V>и увеличить скорость поиска до максимума по всем полям, а не только по отсортированному.


Это не проблема, если БД спроектирована правильно.

V>Где-то с месяц назад я начал делать движок своей собственной БД, и в принципе, он показывал неплохие результаты, но из-за большой сложности программы, и отсутствия опыта проектирования объектно-ориентированных приложений,


Лучше не изобретать велосипед, а посмотреть, что уже сделано. Как правило, в подавляющем большинстве случаеи, разработка собственного движка БД себя не оправдывает, разве что для очень немногих специальных случаев. Разработка базы данных телефонов — это та задача, которая прекрасна решается с использованием общеупотребимых СУБД типа SQL Server или Oracle.

V>мне пришлось приостановить этот процесс и засесть за изучение "Объектно-ориентированного анализа и проектирования" Гради Буча.


Лучше было бы засесть за "Введение в реляционные базы данных" Дейта.

V>За месяц я переписал его несколько раз, на каждой итерации приближаясь к желаемуому результату. Потом я открыл справку по Access, начал читать ее и подумал, что все что я открыл, уже давно придумано. Кроме того, я подумал, что C# — слишком высокоуровневый язык, и может быть, есть смысл не программировать на нем все на низком уровне, а использовать уже готовые сборки для этой цели.


V>После непродолжительного поиска в гугле я пришел к выводу — что SQLite — это то что мне надо.


SQL Server Express, Oracle Express и т.д.

V>Но все же, поскольку теорию реляционных БД я толком не изучал, меня гложат сомнения, можно ли будет осуществить мою задумку, то есть, сделать что-то аналогичное по эффективности задуманному мной движку БД. Архитектура его такая (если вкратце): Вся бд состоит из нескольких файлов. Есть файл "объектов", есть файл "вариантов", и есть файл "свойств". Каждый объект (в данном случае это просто человек) содержит некоторое количество свойств (например, фамилию, имя, отчество, номер телефона и т.д.). Он может и не содержать некоторых свойств, конечно. Какие именно свойства он содержит, указывается в придуманном мной понятии "вариант", проще говоря, это некое подмножество универсума свойств, которые может содержать объект. "Вариант" содержит ID-ы свойств, кроме того, в файле "вариантов" все они ("варианты") отсортированы по своим ID. Хотя, все еще проще — просто порядковый номер "варианта" и является его ID-ом, поскольку варианты добавляются последовательно, ID-ы уже имеющихся вариантов не меняются. В файле объектов хранятся объекты. То есть, собственно говоря, там хранятся последовательности: {ID варианта, ID 1-го ключа, .... , ID n-го ключа}. Каждый объект также имеет свой ID. Что касается ключей, то это экземпляры свойств объекта. Например, фамилии "Иванов", "Петров", "Сидоров" свойства "Фамилия". Каждый ключ имеет свой ID, для большинства свойств достаточно 2 байта, так как, например, навряд ли существует более 65536 всевозможных фамилий, то же самое можно сказать об улицах, именах и т.д, и лишь для номеров телефонов надо 4 байта. Таким образом, достигается экономия описания объектов в файле объектов. Зная ID объекта, мы читаем его "вариант", и узнаем, какие именно "свойства" он содержит, и какова длина ID каждого свойства, далее по очереди читаем ID-ы ключей этих свойств, и извлекаем сами ключи (то есть, фамилию, имя, отчество, номер телефона, и т.д.) из соответствующих файлов. Все просто, но конечно же, необходимо еще и обеспечить поиск по ключам. Тут все немножко сложнее, но тоже в принципе, достаточно красиво. Дело в том, что в файлах ключей хранятся списки ID объектов, которые имеют данный ключ. Конечно, такие списки могут быть достаточно длинны. Например, у ключа "Светланская" свойства "Улица" будет весьма внушительный список ID объектов, потому что улица большая, и народу в ней живет много. Но фишка в том, что все эти списки будут упорядочены по ID, и для этого не надо прикладывать доп. усилий, потому как объекты по идее будут добавляться в БД последовательно, и каждый будет иметь ID на единицу больше предыдущего. Таким образом, у свойств, которыми обладает этот объект, будет добавлен ID объекта, который гарантированно больше последнего. Сами же ключи могут быть упорядочены в алфавитном порядке (правда, это немножко сложней, хотя это я реализовал), но это не принципиально, все равно, ключей не так много, и они могут быть найдены почти мгновенно, за исключением номера телефона, потому разновидностей номеров телефонов как-раз то много. После того, как мы вводим запрос например, найти всех людей с фамилией Иванов и проживающих по улице Светланской, программа находит два списка объектов, и производит их слияние, создавая результирующий список, содержащий только те ID, которые есть в обоих списках. То же самое с запросами по любому количеству свойств. После чего узнать полную информацию об объектах просто. Конечно, тут непаханное поле для оптимизаций, но не будем вдаваться в подробности.


То, что здесь описано, называется Entity-Attribute-Value model (EAV), которая давным-давно использутся при проектировании баз данных. Достоинством ее является высокая гибкость. Недостатки: большая сложность реализации и меньшая по сравнении с традиционными схемами скорость работы. Поэтому применять EAV нужно только там, где это действительно нужно, то есть когда имеется много разнородных объектов, имеющих большое количество разных атрибутов (традиционно EAV используется при разработке медицинских систем для хранения данных пациентов). Я, например, сейчас использую EAV при разработки БД для хранения товаров и их атрибутов для веб-магазина.

Для телефонного справочника лучше использовать традиционные методы проектирования БД.

V>В общем, всем кто осилил это сумбурное послание, большое спасибо. Я очень хотел бы узнать, можно ли в реляционных БД создать что-то подобное по (предположительно высокой) скорости и гибкости.


Несомненно.

V>Разбить большую таблицу на маленькие по полям конечно просто, но как потом искать информацию по запросам, ведь в реляционных БД нельзя создать что-то подобное описанным мной "спискам объектов". Или может я ошибаюсь?

V>Заранее благодарю за ответы. В довершение хочу сказать, что описанная мной архитектура придумана мной, возможно, где-то такое уже есть, если кому что известно, пожалуйста, сообщите.

Тебе нужно для начала изучить проектирование реляционных баз данных (наприрер, здесь). Затем можно поискать уже готовую схему БД и приспособить ее для своих нужд. Например, в первом томе Силверстона в главе 2 есть описание БД с гибкой структурой для хранения адресов и телефонов.

Упор при разработке следует сделать на создание правильной структуры БД, а не на экономию байтов и тому подобное.
Re: Стоит ли ЭТО делать с помощью Реляционных БД?
От: vl690001x Россия  
Дата: 04.08.09 09:28
Оценка:
Огромное спасибо всем ответившим, теперь я знаю в каком направлении "рыть". Все таки форумы — незаменимая вещь в некоторых случаях.
Re[2]: Стоит ли ЭТО делать с помощью Реляционных БД?
От: VGn Россия http://vassilsanych.livejournal.com
Дата: 07.08.09 16:16
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Если точнее, меня интересует такой вопрос. Если реляционная БД разбита на несколько таблиц, и, например, мы производим поиск например по 3-м полям (в 3-х таблицах): "имя", "отчество", "улица проживания", то какой механизм отображения всех записей главной таблицы, содержащих все три искомых ключа? Я так понимаю, для этого в этих трех таблицах должны быть обратные ссылки на списки записей основной таблицы?


Нет обратных ссылок не нужно. Существующие ссылки в основной таблице на строки справочников вполне достаточны.
Хранить имя и отчество в разных таблица смысла нет.
Да и вообще имена обычно из основной таблицы абонентов не выводят.

твой вариант реализуется примерно так:

select * from MainTable t
where t.nameId in
    ( select id from Names n
        where n.Firstname = @firstname
            and n.Secindname = @secondname )
    and t.addressId in
    ( select id from Addresses a
        where a.street = @street )


Адреса обычно вбивать не надо. Есть КЛАДР.
... << RSDN@Home 1.2.0 alpha 4 rev. 1138>>
Re: Стоит ли ЭТО делать с помощью Реляционных БД?
От: Sinclair Россия https://github.com/evilguest/
Дата: 14.08.09 08:22
Оценка:
Здравствуйте, vl690001x, Вы писали:

V>Может быть, это длинное вступление и ни к чему, но изучаю я С# это в общем, с определенной целью — написать программу — телефонный справочник. Дело в том, что имеющийся в наличии телефонный справочник г. Владивостока, содержащий около 4 миллионов телефонных номеров, поразил меня своей неэффективностью.

Да. Все имеющиеся в наличии "телефонные справочники" городов — чудовищно неэффективны.
V>Сейчас, получив некоторые смутные представления о реляционных БД, я понимаю, что архитектура его крайне неэффективна — все данные содержатся в одной-единственной таблице с несколькими полями: телефон, ФИО, улица, дом, квартира. Еще год назад, не зная о теории БД ничего, я придумал способ оптимизации — во первых, разделить ФИО на 3 отдельных поля, во-вторых, устранить дублирование инфрормации.
Да. Банальная нормализация этого справочника, оставаясь в рамках того же движка, уменьшает размер примерно на порядок, и увеличивает быстродействие примерно на два порядка.
В своё время я пытался сделать то же самое со справочником Новосибирска — напоролся на то, что аксесс тупо падал при конверсии из доисторического формата в формат аксесс 2000.
При заливке справочника в MS SQL и нормализации получил ровно те цифры, которые упомянул.

V>Заранее благодарю за ответы. В довершение хочу сказать, что описанная мной архитектура придумана мной, возможно, где-то такое уже есть, если кому что известно, пожалуйста, сообщите.

Про архитектуру EAV я писать не буду — уже всё написали.
Резюме: для вашей конкретной задачи прекрасно подойдёт стандартный MS Access. Если интересно, как на самом деле устроены внутри настоящие СУБД — есть специальная литература, тот же Гарсиа-Молина со товарищи, но её сейчас достаточно сложно найти в продаже.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.