2010-11-23 4 views
8

У меня есть таблица сказать:Ревизии Обращение в Oracle

CREATE TABLE "DataNode" (
    "ID" NUMBER(7,0), 
    "TYPE" NUMBER(7,0), 
    "NAME" VARCHAR2(100), 
    "STATUS" NUMBER(7,0), 
    "REVISION" NUMBER(4,0), 
    "MODIFIEDAT" DATE 
); 

CREATE TABLE "DataNode_Revisions" (
    "ID" NUMBER(7,0), 
    "NODEID" NUMBER(7,0), 
    "TYPE" NUMBER(7,0), 
    "NAME" VARCHAR2(100), 
    "STATUS" NUMBER(7,0), 
    "REVISION" NUMBER(4,0), 
    "MODIFIEDAT" DATE 
) COMPRESS; 

Так что эти две таблицы. Я делаю все свои чтения из «DataNode», и когда происходит изменение, я записываю текущую запись в «DataNode_Revisions», а затем изменяю существующую запись «DataNode». Имеет смысл?

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

«DataNode» постоянно читается множеством пользователей. Тем не менее, очень редко приходится писать. «DataNode_Revisions» читается только по случаю. Я просто беспокоюсь о том, чтобы поддерживать столько таблиц. «DataNode» - одна из ~ 25 таблиц, очень похожих на эту.

ответ

6

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

Если вы хотите спуститься по пути ввода исторических строк в таблице DataNode, вы, вероятно, захотите добавить столбец EXPIRATION_DATE, который является NULL для текущей строки и заполнен для строк с истекшим сроком действия. Затем можно создать индекс-функции на основе EXPIRATION_DATE, которые будут иметь данные только текущей строки, т.е.

CREATE INDEX idx_current_ids 
    ON DataNode((CASE WHEN expiration_date IS NULL THEN id ELSE null END)); 

, который будет использоваться в запросе как

SELECT * 
    FROM DataNode 
WHERE (CASE WHEN expiration_date IS NULL THEN id ELSE null END) = <<some id>> 

Очевидно, что вы» d, возможно, хотите создать представление, которое имеет это условие, а не переписывать его каждый раз, когда вам нужна текущая строка, то есть

CREATE VIEW CurrentDataNode 
AS 
SELECT (CASE WHEN expiration_date IS NULL THEN id ELSE null END) id, 
     type, 
     name, 
     status 
    FROM DataNode; 

SELECT * 
    FROM CurrentDataNode 
WHERE id = <<some value>> 
+0

+1: Идея индекса на основе функций отличная! – 2010-11-23 16:37:09

4

Обычно я использую триггеры для записи в таблицу «Редакции». Да, изменения схемы заставляют вас обновлять зеркальную таблицу и функцию триггера/архива.

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

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

2

У вас есть несколько вариантов. Какое бизнес-требование заставляет вас отслеживать изменения данных?

  • , если вам нужно только сохранить изменения для некоторых «короткого» периода времени, вы можете прочитать данные из UNDO с помощью ретроспективных запросов .. выберите * из таблицы, как из временной метки (л);

  • Если вам нужно сохранить эту информацию на долгосрочной основе, взгляните на функцию t, называемую Oracle Total Recall. Он делает то же самое, что и Flashback Query, но сохраняет изменения на неопределенный срок.

  • Если вам нужно что-то более простое, не добавляйте приложение в «старую» версию строк. Используйте триггер, который заполняет данные.

  • , если система очень занят, вы можете разъединить две таблицы, имеющие промежуточную таблицу, которая используется в качестве «очереди»

2

Это будет зависеть от приложения. Если вы находитесь на 11g, вам может понадобиться посмотреть новый архив данных Flashback. Я только начинаю смотреть на него, чтобы сохранить историю всех наших финансовых и других важных данных.

Смежные вопросы