Предложения по внедрению системы управления документами, в которой в некоторых документах поля времени выполнения заменены - PullRequest
1 голос
/ 01 декабря 2011

Одним из моих приложений является система управления документами, в которой документы хранятся в виде полей BLOB-объектов в БД. Это не вопрос конкретного языка, в любом случае я помещаю Delphi в теги, поскольку это сообщество, к которому я типично задаю вопросы (и многие люди, использующие Delphi, сталкиваются с этими проблемами).

Одна функция, которую мне нужно добавить, это программно добавить некоторые данные в документ. Я делаю простой пример, чтобы понять. Одно поле - это дата создания документа. Для этого пользователь напечатает «тег», например, <DOCUMENT_DATE>, и дата будет автоматически подставлена ​​при извлечении документа из базы данных.

Итак, у меня есть 2 основные проблемы. ONE то, что использовать в качестве «тега». Самое простое - использовать текстовый тег, поэтому просто введите текст в документ, а затем выполните поиск и замену текста (используя, например, MS Word ActiveX). Я уже делаю это для других целей. Альтернативой может быть использование закладок или другой метод.

Другой вопрос строго связан с предыдущим.

Как мне его хранить? Моя первая идея - сохранить документ в БД с «тегами», поэтому, когда он «извлечен», пользователь видит теги, а когда пользователь открывает его (в режиме только для чтения), он видит замещенный текст. (так в первом случае он видит и во втором «12 октября 2011 года»).

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

Альтернатива - хранить документ дважды: один раз с «тегами», а другой с «замещенной версией». Это будет хорошо для производительности: не выполнять поиск и замену, а просто, когда документ открыт в режиме «извлечения», я открою тот, у которого есть теги, а когда открою его в режиме «только чтение», я открою замещенный.

Это, конечно, требует больше памяти, для каждой версии документа (revision1, revision2, ...) мне нужно хранить 2 файла.

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

Но в любом случае я хотел бы услышать некоторые комментарии, поскольку это довольно важное решение.

Ответы [ 2 ]

2 голосов
/ 01 декабря 2011

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

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

Вот пример, слабо вдохновленный вашим сообщением с использованием MySQL:

TABLE document
--------------
id UNSIGNED INTEGER AUTO_INCREMENT PRIMARY KEY,
data BLOB

TABLE tag
------------
id UNSIGNED INTEGER AUTO_INCREMENT PRIMARY KEY,
tag VARCHAR(20)

TABLE tag_link
-------------------
tag_id UNSIGNED INTEGER,
reference_nr UNSIGNED INTEGER,
PRIMARY KEY (tag_id, reference_nr)
FOREIGN KEY (tag_id) REFERENCES tag(id) ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY (reference_nr) REFERENCES post(reference_nr) ON DELETE CASCADE ON UPDATE CASCADE,

TABLE post
----------------
reference_nr UNSIGNED INTEGER NOT NULL,
revision UNSIGNED INTEGER NOT NULL DEFAULT 1,
document_id UNSIGNED INTEGER,
title VARCHAR(255),
creation_date TIMESTAMP,
other_fields .....
PRIMARY KEY (reference_nr, revision),
FOREIGN KEY (document_id) REFERENCES document(id) ON DELETE SET NULL ON CASCADE UPDATE

Теперь вы можете добавлять теги к сообщению, все ревизии публикации имеют одинаковые теги.
Изменениясообщение может ссылаться на один и тот же документ или на разные документы, не нужно дублировать данные.

Если вы хотите получить все последние версии документов с определенными тегами, используйте следующий запрос:

SELECT p.title, d.data, GROUP_CONCAT(t.tag) AS tags
FROM post p
LEFT JOIN d.data ON (p.document_id = d.id)
INNER JOIN taglink tl ON (tl.reference_nr = p.reference_nr)
INNER JOIN tags t ON (tl.tag_id = t.id)
WHERE t.tag IN ('test','test2')
GROUP BY p.reference_nr  /*only works in MySQL because other db's do not support ANSI SQL 2003*/
HAVING p.revision = MAX(p.revision)
ORDER BY p.creation_date DESC
1 голос
/ 01 декабря 2011

Я вижу еще две возможности, которые стоит рассмотреть.

1. Использовать RTF

Если ваши шаблоны документов являются документами Word, я бы предпочел хранить их как RTF.

RTF - это просто ASCII, и даже если это проприетарный формат, он хорошо документирован и может быть легко проанализирован. Word может сохранять его содержимое и читать его как RTF. Если у вас есть изображения внутри, они могут расти, но вы можете сжать их перед сохранением в виде BLOB в вашей базе данных (и вы можете вставлять изображения EMF).

Затем вы можете очень быстро обработать содержимое RTF в своем коде, изменив все <DOCUMENT_DATE>, используя последнюю версию значения поля даты.

Я использую эту технику в нескольких приложениях, и она дает очень хорошие результаты. Посмотрите, например, как наш SynProject tool генерирует документы Word из простого текста, заменяя теги, устанавливая закладки или индексы на лету. С RTF вы можете сделать гораздо больше, чем просто заменить тег, но легко создать целый документ.

Для ввода конечного пользователя вместо Word можно использовать базовый TRichEdit или более продвинутый (но не бесплатный) TRichView.

Вы можете рассмотреть возможность использования HTML вместо RTF, но он гораздо менее удобен для печати. ​​

2. Использовать механизм отчетов

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

Наши открытые исходные коды можно использовать из простого класса отчетности для простого создания содержимого файла, предварительного просмотра его на экране и / или печати / экспорта в формате PDF. Работать с RTF гораздо проще, но макет должен быть установлен в вашем коде или с текстовыми / вики-подобными шаблонами, которые должны храниться в вашей БД.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...