Идеи о проектировании баз данных для получения [закрытых] журналов аудита

расширили очень хорошее решение «с форматной строкой» из JSmyth , чтобы также поддерживать

  • все остальные ] console.log вариации (log, debug, info, warn, error)
  • , включая параметр гибкости строки метки времени (например, 09:05:11.518 ] против 2018-06-13T09:05:11.518Z)
  • , включая запасной вариант в случае console или его функции не существуют в браузерах

.

var Utl = {

consoleFallback : function() {

    if (console == undefined) {
        console = {
            log : function() {},
            debug : function() {},
            info : function() {},
            warn : function() {},
            error : function() {}
        };
    }
    if (console.debug == undefined) { // IE workaround
        console.debug = function() {
            console.info( 'DEBUG: ', arguments );
        }
    }
},


/** based on timestamp logging: from: https://stackoverflow.com/a/13278323/1915920 */
consoleWithTimestamps : function( getDateFunc = function(){ return new Date().toJSON() } ) {

    console.logCopy = console.log.bind(console)
    console.log = function() {
        var timestamp = getDateFunc()
        if (arguments.length) {
            var args = Array.prototype.slice.call(arguments, 0)
            if (typeof arguments[0] === "string") {
                args[0] = "%o: " + arguments[0]
                args.splice(1, 0, timestamp)
                this.logCopy.apply(this, args)
            } else this.logCopy(timestamp, args)
        }
    }
    console.debugCopy = console.debug.bind(console)
    console.debug = function() {
        var timestamp = getDateFunc()
        if (arguments.length) {
            var args = Array.prototype.slice.call(arguments, 0)
            if (typeof arguments[0] === "string") {
                args[0] = "%o: " + arguments[0]
                args.splice(1, 0, timestamp)
                this.debugCopy.apply(this, args)
            } else this.debugCopy(timestamp, args)
        }
    }
    console.infoCopy = console.info.bind(console)
    console.info = function() {
        var timestamp = getDateFunc()
        if (arguments.length) {
            var args = Array.prototype.slice.call(arguments, 0)
            if (typeof arguments[0] === "string") {
                args[0] = "%o: " + arguments[0]
                args.splice(1, 0, timestamp)
                this.infoCopy.apply(this, args)
            } else this.infoCopy(timestamp, args)
        }
    }
    console.warnCopy = console.warn.bind(console)
    console.warn = function() {
        var timestamp = getDateFunc()
        if (arguments.length) {
            var args = Array.prototype.slice.call(arguments, 0)
            if (typeof arguments[0] === "string") {
                args[0] = "%o: " + arguments[0]
                args.splice(1, 0, timestamp)
                this.warnCopy.apply(this, args)
            } else this.warnCopy(timestamp, args)
        }
    }
    console.errorCopy = console.error.bind(console)
    console.error = function() {
        var timestamp = getDateFunc()
        if (arguments.length) {
            var args = Array.prototype.slice.call(arguments, 0)
            if (typeof arguments[0] === "string") {
                args[0] = "%o: " + arguments[0]
                args.splice(1, 0, timestamp)
                this.errorCopy.apply(this, args)
            } else this.errorCopy(timestamp, args)
        }
    }
}
}  // Utl

Utl.consoleFallback()
//Utl.consoleWithTimestamps()  // defaults to e.g. '2018-06-13T09:05:11.518Z'
Utl.consoleWithTimestamps( function(){ return new Date().toJSON().replace( /^.+T(.+)Z.*$/, '$1' ) } )  // e.g. '09:05:11.518'

41
задан Esteban Küber 21 September 2009 в 12:59
поделиться

3 ответа

Используйте «Вставить только базы данных»

Основная идея состоит в том, что вы никогда не обновляете и не удаляете данные.

Каждая таблица имеет 2 столбца даты и времени из и ] до .

Они начинаются со значения NULL в каждом (от начала времени до конца времени)

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

Вы считываете данные из таблицы через представление, в котором есть куда = null в нем.

Этот метод также дает вам картину состояния вашей базы данных в любой момент времени.

РЕДАКТИРОВАТЬ

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

24
ответ дан 27 November 2019 в 00:46
поделиться

Посмотрите, содержит ли мой ответ на другой вопрос о ведении журнала базы данных нужную информацию. Его можно найти здесь ...

Плюсы, минусы и недостатки таблиц истории - с использованием триггеров, sproc или на уровне приложения

1
ответ дан 27 November 2019 в 00:46
поделиться

Используйте базу данных «только для вставки», как описано Ширазом Бхаджи, но вы можете использовать более простую технику. Для каждой таблицы, для которой необходимо вести данные аудита, просто добавьте дополнительный столбец для параметра «Время обновления», по умолчанию - «сейчас». Когда вы вносите изменения в запись, вместо обновления просто вставьте все свои данные; столбец UpdatedTime получит текущее время.

Обратите внимание, что этот метод означает, что вы должны нарушить или пересмотреть ваши ограничения UNIQUE; вы можете сохранить первичный ключ, но уникальность становится составной частью вашего первичного ключа и вашего параметра UpdatedTime.

Этот метод имеет то преимущество, что дает вам известный диапазон исторических данных для каждой записи в таблице (каждая запись действительна для заданное время, если это ТОП 1 записей WHERE TimeOfInterest> UpdatedTime ORDER BY UpdatedTime DESC) с небольшими накладными расходами (только один столбец в таблице). Также вполне возможно преобразование из таблиц без использования этого метода, с помощью простого ALTER TABLE, чтобы добавить один столбец (который вы можете назвать последовательно). Затем вам просто нужно изменить ваши UNIQUE-ограничения, чтобы использовать их текущие ограничения и столбец UpdatedTime, а некоторые запросы нужно будет изменить.

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

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

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

14
ответ дан 27 November 2019 в 00:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: