Форум: "Базы";
Текущий архив: 2004.09.12;
Скачать: [xml.tar.bz2];
ВнизОгромный размер БД Найти похожие ветки
← →
Сергей Плоткин (2004-08-12 23:45) [0]Уважаемые знатоки,
Передо мной стоит такая проблема:
На данный момент пишу каталогизатор компакт-дисков. Программа использует базу данных (Absolute Database).
В программе есть процедура сканирования компакт-дисков на предмет файлов и есть таблица "Files", в которую эта процедура записывает каждый файл с выбранного компакт-диска (не сам файл, а его название, конечно), как отдельную строку. В этой таблице 60 колонок (на каждый файл куча параметров - атрибуты, размер, теги мп3, видео-информация, информация о изображениях, архивах и т.п.).
А теперь самое ужасное: закончил работу над процедурой и сделал пробный прогон (до этого запись в таблицу я закомментировал): взял диск с ~ 10000 файлами и запустил. И о"ужас, после добавления в таблицу 9996 файлов, файл базы данных стал занимать 27 мегабайт! Думал, ну может это на первый раз такое, потом меньше будет - запустил еще раз - 56 мегабайт!
Размеры каждой колонки я уже уменьшил, насколько это возможно. PageSize таблицы - 2550 (минимум, просто).
Господа знатоки, помогите пожалуйста, возможно ли как-то существенно уменьшить размер базы данных? Возможно есть встроенное сжатие какое-либо? Ведь 10000 строк текстовой информации должно сильно жаться...
p.s. Программа будет Freeware... Как я в глаза буду смотреть бедным пользователям, которые в обморок упадут после первого отсканированного диска?.. :)
← →
Алхимик © (2004-08-13 00:03) [1]Пересмотри структуру БД
Например в одну таблицу пиши инфу по
.mp3 (имя, теги и т.д.) в другую про .doc ...
Идея в том чтобы в одной записи было не 60 полей из которых не все актуальны, а не больше 10 например.
← →
sniknik © (2004-08-13 00:13) [2]очень сушественно можно уменьшить если сделать настройку в которой ограничивать отслеживаемые файлы... ну типа проставляеш галочки на тех что тебя интересует (вернее меня, юзера), все остальное мне пофиг и можно не сохранять.
и немного за счет нормализации... не хранить все 60полей в одной таблице а выделить только основное, остальное с связываемых файлах. ну зачем тебе колонки о видео если файл текстовый? а так только тип в основных полях храниш и разные таблици с инфой о разных типах.
и еще немного.. ;о) есть там в этом Absolute Database var поля? ну типа что в mssql/access если поле char(60) и ему 5 символов присвоить запись займет все одно 60 символов... а вот если varchar(60) то всего 4(указатель) + 5(данные) символов. экономия однакою ;о)
ну и еще чуть чуть... ;о)) юникод база держит? если да и по умолчанию включено то это *2 размер всех строк. найди и выключи. (если есть)
может еще чего можно придумать но... както не видится отсюда. ;)
← →
Сергей Плоткин (2004-08-13 00:53) [3]
> и немного за счет нормализации... не хранить все 60полей
> в одной таблице а выделить только основное, остальное с
> связываемых файлах. ну зачем тебе колонки о видео если файл
> текстовый? а так только тип в основных полях храниш и разные
> таблици с инфой о разных типах.
Ок, так и сделаю...
> и еще немного.. ;о) есть там в этом Absolute Database var
> поля? ну типа что в mssql/access если поле char(60) и ему
> 5 символов присвоить запись займет все одно 60 символов...
> а вот если varchar(60) то всего 4(указатель) + 5(данные)
> символов. экономия однакою ;о)
VarChar нет. Есть только VarBytes. Variable number of bytes (binary storage) пишут в хелпе. Это не то случайно?
> ну и еще чуть чуть... ;о)) юникод база держит? если да и
> по умолчанию включено то это *2 размер всех строк. найди
> и выключи. (если есть)
Поддержки Юникода, поверхностно взглянув, не нашел...
p.s. Все равно, получается, что существенно уменьшить размер не удастся?.. Вообще, я предполагал, что размер структуры каждого диска будет занимать не более 300-400 кб, а так я думаю, все равно даже при всех условиях, описанных выше, каждая структура будет 3-6 мб... Что же будет, когда в базе будет 100 дисков.
Поэтому, сразу назревает 2 вопроса:
1) Неужели в БД не бывает сжатия всех полей?
2) Насчет Access. Если создавать базу Access, то необходимо ли будет наличие каких-либо DLL Access (или самой установленной MS Access) на компьютере у стороннего пользователя? Слышал, что если управлять через ADO, то ничего такого пользователю не потребуется.
← →
sniknik © (2004-08-13 08:20) [4]> будет 3-6 мб... Что же будет, когда в базе будет 100 дисков.
300-600mb. ;о))
не знаю что ты храниш, но возможно часть инфы можно вообще выкинуть, если есть такая что без самого диска недействительна/неиспользуется. подумай.
> то ничего такого пользователю не потребуется.
потребуется, а так говорят потому что в 95% случаев уже все установлено (ставится с системой, а если не ставится то есть вероятность что ктото до тебя поставил (многие используют))
← →
46_55_41_44 © (2004-08-13 08:57) [5]Предлагаю тебе ввести собственную кодировку...
Например:
Бери расширение файлов, как уникальный ключ! (Файлы без расширения можно назвать например Untyped)
Затем создаешь таблицу:
FileType - String - Key Field
FileName - String - Key Field
FilePath - String - Key Field
FileAttributes - String
FileSize - LongInt
В FileType записываешь расширение файлов *.mp3, *.txt всу что угодно (Файлы без расширения -Untyped)
С FileName, FilePath, FileSize думаю все ясно...
Вот теперь самое главное...
FileAttributes...
Предлагаю вот что...
Ну сколько может быть например случаев и всяких там аттрибутов для файлов... Не очень много... Так вот...
В первые 2 символа записывай например информацию о аттрибутах..
Там всего 4 случая: Archive, Read-Only, Hidden, System... так вот 01 - Archive, 02- Read-Only... и т.д.
Во вторые 2 символа еще что-то... и т.д.
И так ты сможешь записать 255 div 2 = 122 набора свойств файлов... помоему достаточно... и у каждого свойства по 01..99 вариантов... Вариант 00 оставишь нп отсутствие данного типа в файле...
В конце у тебя получится строка типа 010206020120... (смотря сколько информации будешь писать)... Примечание: Все строки должны быть одинаковой длины...
Для этого тебе советую написать 2 функции...Одна для записи в базу другая для считывания...
и все...
работа не очень легкая... но зато нагрузка с БД перейдет на прогу... БД уменьшится до пары сотен кБ... если не меньше!!!
← →
Anatoly Podgoretsky © (2004-08-13 09:10) [6]2550 * 10000 - 25 500 000 байт без учета служебных расходов.
Уменьшить можно за счет нормализации, см. выше и за счет правильных типов полей и смены базы данных. А 10000 это не большое количество, может быть значительно больше.
Absolute Database это случайно не ADS и ты видимо выбрал dBase формат или их сообственный, не серверный. Эта база мало подходяше для указаных целей. Смотреть в сторону клиент серверных баз - MSDE, Firebird и других. Выбрать правильные типы и нормальную нормализацию. Сможешь снизить раза в два-три.
Но работать с базами большего размера и обижаться на размер нелепо. Нормальное явление 1-2 гб база.
← →
Anatoly Podgoretsky © (2004-08-13 09:11) [7]Приведи так структуру таблицы (таблиц)
← →
46_55_41_44 © (2004-08-13 09:25) [8]
> Anatoly Podgoretsky © (13.08.04 09:10) [6]
> 2550 * 10000 - 25 500 000 байт без учета служебных расходов
При всем уважении к вам Анатолий... я не претендую на ваши лавры...
Но все-таки...
255 * 10 000 = 2 550 000, что уже помоему лучше чем 40-50 мегов... и к тому же не обязательно брать все 255 символов... Думаю, что 50 хватит с лихвой!!! тогда 50 * 10 000 = 500 000, о чем я и говорил!!! Можно использовать не 2 символа для свойств, а 1... Тогда вариантов будет всего 9... ну и что... помоему хватит... Тогда можно урезать еще размер символов на 20...
Получается 30 * 10 000 = 300 000
С другой стороны вы конечно же правы... мне бы его проблемы... что делать с БД размеров в несколько ГБ...
← →
46_55_41_44 © (2004-08-13 09:28) [9]Все сказанное мной является лишь моим мнением... Не претендую на абсолютность его (мнения)
← →
Danilka © (2004-08-13 09:34) [10][8] 46_55_41_44 © (13.08.04 09:25)
> Получается 30 * 10 000 = 300 000
Что-то я тебя не пойму, как полный путь с именем файла и со всеми аттрибурами влезет в 30 байт?
Сергей Плоткин
Если на самом деле очень надо уменьшить базу, то как вариант, сделать одну деревянную таблицу - каталог, с тремя полями:
id - integer
parent_id - integer
folder_name - varchar
а в таблице файлов писать не полный путь, а только имя файла, и в отдельную колонку id каталога.
Тоже, в какой-то мере нормализация. :))
← →
46_55_41_44 © (2004-08-13 09:36) [11]
> Что-то я тебя не пойму, как полный путь с именем файла и
> со всеми аттрибурами влезет в 30 байт?
Внимательнее читай, что я предлагал!!!
путь к файлу как раз в другом поле...
> 46_55_41_44 © (13.08.04 08:57) [5]
> Предлагаю тебе ввести собственную кодировку...
> Например:
> Бери расширение файлов, как уникальный ключ! (Файлы без
> расширения можно назвать например Untyped)
> Затем создаешь таблицу:
> FileType - String - Key Field
> FileName - String - Key Field
> FilePath - String - Key Field
> FileAttributes - String
> FileSize - LongInt
← →
Danilka © (2004-08-13 09:43) [12][11] 46_55_41_44 © (13.08.04 09:36)
В другом поле или другой таблице?
В любом случает, ты написал: 30 * 10 000 = 300 000
То-есть, по-твоему размер записи, то-есть размер всех полей записи всего 30 байт...
Если-же в другой таблице, то она тоэе будет в БД лежать, ее как-бы тоже посчитать надо. :))
← →
Anatoly Podgoretsky © (2004-08-13 09:50) [13]46_55_41_44 © (13.08.04 09:25) [8]
Почему ты умножаешь 255 а не 2550, он же точно указал размер
← →
46_55_41_44 © (2004-08-13 10:15) [14]Ну это его представление ...
я же предлагаю изменить структуру базы...
а 255 умножаю потому, что String = 0..255
И это самый максимум...
Правда это будет размер лишь одного поля...
В общей сложности будет 3 890 000
Объясняю почему...
FileType - максимум 5 символов 5 * 10 000 = 50 000
FileName - максимум 100 символов... можно и чуть больше - 100 * 10 000 = 1 000 000
FilePath - 255 символов = 255 * 10 000 = 2 550 000 можно и уменьшить в принципе... но берем по максимуму...
FileAttributes - 30 символов - 30 * 10 000 = 300 000
FileSize - 4 байта, если не ошибаюсь... 4 * 10 000 = 40 000
итого
50 000 + 1 000 000 + 2 500 000 + 300 000 + 40 000 = 3 890 000 Bytes
Это просто спонтанная идея... Я не говорю, что ее надо именно применить... просто привожу факты!
← →
Danilka © (2004-08-13 10:27) [15][14] 46_55_41_44 © (13.08.04 10:15)
Во-первых, String может быть и больше 255, во-вторых, полный путь тоже сможет быть больше 255, в третьих, где вот-это: "куча параметров - атрибуты, размер, теги мп3, видео-информация, информация о изображениях, архивах"?
← →
Danilka © (2004-08-13 10:30) [16][14] 46_55_41_44 © (13.08.04 10:15)
Возможно, информация о файлах у него занимает места и меньше чем в приведенном тобой примере: 3 890 000, но есть еще и куча другой информации.
← →
46_55_41_44 © (2004-08-13 10:41) [17]не ругайте пианиста.. он играет как может ))))
Это всего лишь информация... иначе удобнее было бы просто переписать всю базу в бд...
Так что все-таки помоему я прав...
а на счет String да какая разница... String или WideString.. Принцип надо понять!!
← →
46_55_41_44 © (2004-08-13 10:50) [18]вернее все файлы в БД... сорри ))
← →
sniknik © (2004-08-13 11:03) [19]сохранение пути тоже можно уменьшить, сделать дерево каталогов, аналогично что в реально на диске наблюдаем...
т.е. каталог и у него дети подкаталоги/файлы в подкаталоге то же самое...
полный путь придется получать собирая всю связку. но зато все 10 тыс. файлов будут занимать на весь путь до них меньше места.
← →
46_55_41_44 © (2004-08-13 11:45) [20]
> sniknik © (13.08.04 11:03) [19]
Во-во... маладес слющий... Тебе пальшой пальшой кафкаский сипасиба!! :)))
← →
Сергей Плоткин (2004-08-13 11:45) [21]
> 46_55_41_44 © (13.08.04 08:57) [5]
> Предлагаю тебе ввести собственную кодировку...
Тогда придется отказываться от большинства разнообразных запросов в поиске файлов на диске.
> Anatoly Podgoretsky © (13.08.04 09:10) [6]
> см. выше и за счет правильных типов
> полей и смены базы данных.
Программа будет распространяться обычным пользователям. Что мне им, предлагать MS SQL Server ставить, что-ли?..
> Absolute Database это случайно не ADS и ты видимо выбрал
> dBase формат или их сообственный, не серверный.
Нет, это не ADS. Вот выдержка из описания:
- нет DLL (engine базы данных компилируется прямо в EXE-файл)
- поддержка SQL"92 (DDL и DML)
- база данных - в одном файле
- 100% совместимость со стандартными DB-aware элементами управления
- сильное шифрование
- BLOB сжатие
- доступен полный исходный код
- не нужно платить лицензионные отчисления
- бесплатно для персонального использования
> Anatoly Podgoretsky © (13.08.04 09:11) [7]
> Приведи так структуру таблицы (таблиц)
Таблица с файлами следующая:
Table.AdvFieldDefs.Add("FileID", aftAutoInc, 10, True);
Table.AdvFieldDefs.Add("CDID", aftInteger, 10);
Table.AdvFieldDefs.Add("CDNumID", aftInteger, 1);
Table.AdvFieldDefs.Add("Filename", aftString, 255);
Table.AdvFieldDefs.Add("FilePath", aftString, 255);
Table.AdvFieldDefs.Add("IsFolder", aftBoolean);
Table.AdvFieldDefs.Add("CreateDate", aftDateTime, 20);
Table.AdvFieldDefs.Add("AccessDate", aftDateTime, 20);
Table.AdvFieldDefs.Add("ChangeDate", aftDateTime, 20);
Table.AdvFieldDefs.Add("ReadOnlyF", aftBoolean);
Table.AdvFieldDefs.Add("HiddenF", aftBoolean);
Table.AdvFieldDefs.Add("ArchiveF", aftBoolean);
Table.AdvFieldDefs.Add("SystemF", aftBoolean);
Table.AdvFieldDefs.Add("Size", aftInteger, 10);
Table.AdvFieldDefs.Add("AppType", aftString, 5);
Table.AdvFieldDefs.Add("AppIcon", aftGraphic);
Table.AdvFieldDefs.Add("ID1Artist", aftString, 30);
Table.AdvFieldDefs.Add("ID1Title", aftString, 30);
Table.AdvFieldDefs.Add("ID1Album", aftString, 30);
Table.AdvFieldDefs.Add("ID1Comment", aftString, 30);
Table.AdvFieldDefs.Add("ID1Year", aftInteger, 4);
Table.AdvFieldDefs.Add("ID1Genre", aftString, 30);
Table.AdvFieldDefs.Add("ID2Artist", aftString, 255);
Table.AdvFieldDefs.Add("ID2Title", aftString, 255);
Table.AdvFieldDefs.Add("ID2Album", aftString, 255);
Table.AdvFieldDefs.Add("ID2Comment", aftString, 255);
Table.AdvFieldDefs.Add("ID2Year", aftInteger, 255);
Table.AdvFieldDefs.Add("ID2Genre", aftString, 255);
Table.AdvFieldDefs.Add("MediaLength", aftInteger, 20);
Table.AdvFieldDefs.Add("MediaBitrate", aftInteger, 5);
Table.AdvFieldDefs.Add("MediaSampleRate", aftInteger, 5);
Table.AdvFieldDefs.Add("MediaMode", aftInteger, 2);
Table.AdvFieldDefs.Add("PictureHeight", aftInteger, 5);
Table.AdvFieldDefs.Add("PictureWidth", aftInteger, 5);
Table.AdvFieldDefs.Add("PictureThumbnail", aftGraphic);
Table.AdvFieldDefs.Add("VideoHeight", aftInteger, 5);
Table.AdvFieldDefs.Add("VideoWidth", aftInteger, 5);
Table.AdvFieldDefs.Add("VideoCodec", aftString, 10);
Table.AdvFieldDefs.Add("VideoLength", aftInteger, 20);
Table.AdvFieldDefs.Add("VideoBitrate", aftInteger, 5);
Table.AdvFieldDefs.Add("VideoFPS", aftInteger, 2);
Table.AdvFieldDefs.Add("VideoAudioBitrate1", aftInteger, 5);
Table.AdvFieldDefs.Add("VideoAudioBitrate2", aftInteger, 5);
Table.AdvFieldDefs.Add("VideoAudioSampleRate1", aftInteger, 5);
Table.AdvFieldDefs.Add("VideoAudioSampleRate2", aftInteger, 5);
Table.AdvFieldDefs.Add("VideoAudioChannels1", aftInteger, 5);
Table.AdvFieldDefs.Add("VideoAudioChannels2", aftInteger, 5);
Table.AdvFieldDefs.Add("VideoThumbnail", aftGraphic);
Table.AdvFieldDefs.Add("IsArchive", aftBoolean);
Table.AdvFieldDefs.Add("ArcAllFileSize", aftInteger, 10);
Table.AdvFieldDefs.Add("ArcAllFileComprSize", aftInteger, 10);
Table.AdvFieldDefs.Add("ArcCurFileRatio", aftInteger, 3);
Table.AdvFieldDefs.Add("ArcCurFileSize", aftInteger, 10);
Table.AdvFieldDefs.Add("ArcCurFileComprSize", aftInteger, 10);
Table.AdvFieldDefs.Add("ArcCurFileHostOS", aftString, 30);
Table.AdvFieldDefs.Add("ArcCurFileCRC", aftInteger, 10);
Table.AdvFieldDefs.Add("ArcCurFileDateTime", aftDateTime, 20);
Table.AdvFieldDefs.Add("ArcCurFileAttributes", aftString, 4);
Table.AdvFieldDefs.Add("CustomComment", aftFormattedMemo);
Table.CreateTable;
> sniknik © (13.08.04 11:03) [19]
> сохранение пути тоже можно уменьшить, сделать дерево каталогов,
> аналогично что в реально на диске наблюдаем...
> т.е. каталог и у него дети подкаталоги/файлы в подкаталоге
> то же самое...
> полный путь придется получать собирая всю связку.
Не совсем понял. Можно это как-то поподробнее разъяснить?..
← →
Danilka © (2004-08-13 11:47) [22]
> Можно это как-то поподробнее разъяснить?..
См: [10] Danilka © (13.08.04 09:34) я там немного попдробнее написал. :))
← →
Sandman25 © (2004-08-13 11:49) [23]aftString - плохой тип. Особенно если длина 255.
aftVarString там есть?
← →
Сергей Плоткин (2004-08-13 11:50) [24]
> Danilka © (13.08.04 11:47) [22]
> я там немного попдробнее написал. :))
Нет, спасибо... :) Не пойдет...
← →
Сергей Плоткин (2004-08-13 11:51) [25]
> Sandman25 © (13.08.04 11:49) [23]
> aftString - плохой тип. Особенно если длина 255.
> aftVarString там есть?
В том то и дело, что нет... Есть VarBytes, но я еще не глядел, что это такое...
← →
46_55_41_44 © (2004-08-13 11:54) [26]Убери все типы aftGraphic ... Зачем тебе хранить в базе изображения??? не понятно...
Если уберешь... то всю твою БД можно подвести к моему вышеописанному методу!
← →
Danilka © (2004-08-13 11:55) [27][24] Сергей Плоткин (13.08.04 11:50)
> Не пойдет...
Интересно, почему? Религиозные соображения? Ты думаешь в [19] sniknik © (13.08.04 11:03) что-то другое написано?
← →
Danilka © (2004-08-13 11:59) [28]Ну и, конечно-же, нормализация тебя спасет.
← →
sniknik © (2004-08-13 12:07) [29]Danilka © (13.08.04 11:47) [22]
упс... именно это и имел ввиду.
Сергей Плоткин (13.08.04 11:50) [24]
> Нет, спасибо... :) Не пойдет...
это ты зря
получится чтото вроде
1, 0, "D:\Program Files\Borland\Delphi7\MergeModules"
2, 1, "bdemmcfg.exe"
3, 1, "DatabaseRTL.Msm"
4, 1, "DatabaseVCL.Msm"
...
10000, 1, "TeeChart.Msm"
на самом деле еще хуже ;о), т.к. каждый подкаталог будет отдельно.
прикинь экономию...
> Нет, это не ADS. Вот выдержка из описания: ...
нда, негусто. замени хоть на тот же access с его вар полями отключенным юникодом, выигрыш уже будет.
а в этом слуячае похоже у тебя и пустая запись занимает полный обьем. (наследие dbf ;о))
← →
Сергей Плоткин (2004-08-13 12:19) [30]
> Интересно, почему? Религиозные соображения?
Да, нет... Извини, я сначала не так понял, что ты мне предложил. А ты думаешь, что вынесение папок в отдельную таблицу сильно уменьшит размер базы? Вроде, размер основательно уменьшиться лишь в том случае, если на диске очень мало папок и очень много файлов, лежащих в этих папках...
> нда, негусто. замени хоть на тот же access с его вар полями
> отключенным юникодом, выигрыш уже будет.
> а в этом слуячае похоже у тебя и пустая запись занимает
> полный обьем. (наследие dbf ;о))
Похоже, так и придется сделать...
← →
Iconka © (2004-08-13 13:10) [31]
> А ты думаешь, что вынесение папок в отдельную таблицу сильно
> уменьшит размер базы? Вроде, размер основательно уменьшиться
> лишь в том случае, если на диске очень мало папок и очень
> много файлов, лежащих в этих папках...
Да палюбому. У тебя в строке будет хранится имя папки, а не полный путь к ней.
← →
Anatoly Podgoretsky © (2004-08-13 13:31) [32]Нужна нормализация, информация постоянно дублируется, как минимум существуют такие понятия как - диск, альбом, исполнитель, путь, песни (или фильмы - иначе произвеление) и т.д. Поэтому неудивительно, что у тебя очень большой размер. Раздели таблицу на несколько таблиц, как минимум диски и произведения, хотя этого не достаточно.
Другими словами марш за учебники по теории реляционных баз данных.
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2004.09.12;
Скачать: [xml.tar.bz2];
Память: 0.57 MB
Время: 0.036 c