2009-04-03 4 views
0

У меня есть большой стол сервера SQL, который выглядит примерно так:Работа с дублированием данных в SQL Server

 
ImageId int 
Page int 
FSPath varchar(256) 
ImageFrame int 
... 

В таблице хранятся записи для каждой страницы нескольких файлов изображений. Это делается для того, чтобы таблица отображала изображения, где каждая страница представлена ​​другим файлом, и многостраничные файлы изображений, содержащие страницы в одном файле. Когда я имею дело с многостраничной настройкой, значение столбца FSPath точно дублируется для каждой страницы в пределах того же документа, который ест много места (только эта таблица в настоящее время составляет ~ 5 ГБ). Кажется очень расточительным дублирование данных таким образом, но я не смог найти альтернативное решение, которым я доволен.

В шаблоне использования для этой таблицы преобладают поисковые запросы на основе первичного ключа (ImageId/Page) для пути (и других столбцов), но мне также необходимо иметь возможность эффективно обрабатывать вставку новых данных и случайное удаление.

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

Я надеялся, что смогу создать обновляемый вид объединенных таблиц и позволить SQL Server сделать для меня магию, но я получаю сообщение: View или function 'Scrap.dbo.PageView' не является обновляемым, поскольку модификация влияет на несколько базовых таблиц. Попытка выполнить вставку.

Есть ли разумный способ сделать это, что я просто отсутствую, или мне не повезло?

ответ

1

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

Как выглядит файловая система? Если это глубокое дерево каталогов, можно ли каким-либо образом абстрагировать это в отдельной таблице поиска, а не сохранять информацию о пути каждый раз? Например, что-то вроде:

Таблица ПУТЕЙ:

 
ID PATHNAME  PARENT 
int varchar(128) int, FK on PATHS.ID 
--- ------------ -------------------- 
1 /    NULL 
2  images   1 
3  dir1   2 
4  dir2   2 

Или еще быстрее реконструкции пути, вы просто хранить все это, до тех пор, пока вы просто экономить каждый путь один раз. Таким образом, вам не придется беспокоиться о рекурсии обратно до корня, чтобы собрать путь каждый раз:

 
ID PATHNAME 
int varchar(128) 
--- ------------ 
1 /
2  /images 
3  /images/dir1 
4  /images/dir2 

Затем вы можете изменить определение вашей таблицы быть:

 
ImageId int 
Page int 
FileName varchar(256) 
Path int, FK to PATHS.ID 
ImageFrame int 
... 

и, возможно, спасти немного места, особенно если оно очень глубокое.

0

Я думаю, что вы правы - создание новой таблицы только для хранения уникальных путей может занимать больше места, чем оставлять дублированные данные в исходной таблице. Кроме того, это усложняет запросы и обновления. Это зависит от количества дубликатов, конечно.

0

Я смущен о реальной проблеме? У вас проблемы с производительностью или 5 концертов действительно так дорого?Если производительность является проблемой, меньшая таблица может быть не решением. Я бы исследовал изменение FSPath на char (256). Это займет больше места, но ваши данные будут лучше соответствовать на жестком диске, а должен помочь производительности. Я бы также поддержал изменение схемы, как вы описали, но это, если это невозможно, потому что потребители не могут/не будут изменять код, вам может понадобиться построить какой-то тест, чтобы показать, что это стоит того.

+0

У меня возникают проблемы с производительностью из-за пейджинга на диске, который возникает, когда я загружаю эти записи. Я исследовал подход с фиксированной шириной, но учитывая, что моя средняя длина пути составляет 25 символов, переключение на char (256) будет почти 10-кратным моим требованиям к хранению и вызовет больше ошибок диска. – 2009-04-03 17:09:19