Обработка изменений в Oracle - PullRequest
8 голосов
/ 23 ноября 2010

У меня есть таблица, которая говорит:

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 таблиц, очень похожих на эту.

Ответы [ 4 ]

6 голосов
/ 23 ноября 2010

Будут ли какие-либо последствия для производительности при хранении старых строк в таблице 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>>

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

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>>
4 голосов
/ 23 ноября 2010

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

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

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

2 голосов
/ 23 ноября 2010

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

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

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

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

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

2 голосов
/ 23 ноября 2010

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

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