import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
public class test {
public static class Person {
public String name;
public int id;
public Date hireDate;
public Person(String iname, int iid, Date ihireDate) {
name = iname;
id = iid;
hireDate = ihireDate;
}
public String toString() {
return name + " " + id + " " + hireDate.toString();
}
// Comparator
public static class CompId implements Comparator<Person> {
@Override
public int compare(Person arg0, Person arg1) {
return arg0.id - arg1.id;
}
}
public static class CompDate implements Comparator<Person> {
private int mod = 1;
public CompDate(boolean desc) {
if (desc) mod =-1;
}
@Override
public int compare(Person arg0, Person arg1) {
return mod*arg0.hireDate.compareTo(arg1.hireDate);
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
SimpleDateFormat df = new SimpleDateFormat("mm-dd-yyyy");
ArrayList<Person> people;
people = new ArrayList<Person>();
try {
people.add(new Person("Joe", 92422, df.parse("12-12-2010")));
people.add(new Person("Joef", 24122, df.parse("1-12-2010")));
people.add(new Person("Joee", 24922, df.parse("12-2-2010")));
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Collections.sort(people, new Person.CompId());
System.out.println("BY ID");
for (Person p : people) {
System.out.println(p.toString());
}
Collections.sort(people, new Person.CompDate(false));
System.out.println("BY Date asc");
for (Person p : people) {
System.out.println(p.toString());
}
Collections.sort(people, new Person.CompDate(true));
System.out.println("BY Date desc");
for (Person p : people) {
System.out.println(p.toString());
}
}
}
В то время как Вы в нем, также записываете пользователя, который внес изменение.
дефект с дизайном отдельной таблицы (в дополнение к производительности соединения, выделенной другими), - то, что это делает предположение, что каждый таблица имеет столбец идентификационных данных для ключа. Это не всегда верно.
, Если Вы используете SQL Server, новая поддержка версии 2008 года что-то, которое они звонят Change Data Capture
, который должен устранить много боли, о которой Вы говорите. Я думаю, что Oracle может иметь что-то подобное также.
Обновление: По-видимому, Oracle называет это тем же самым как SQL Server. Или скорее SQL Server называет это тем же самым как Oracle, так как реализация Oracle была на первом месте ;)
http://www.oracle.com/technology/oramag/oracle/03-nov/o63tech_bi.html
Я использовал дизайн, где каждая таблица, которая будет контролироваться, имела две таблицы:
create table NAME (
name_id int,
first_name varchar
last_name varchar
-- any other table/column constraints
)
create table NAME_AUDIT (
name_audit_id int
name_id int
first_name varchar
last_name varchar
update_type char(1) -- 'U', 'D', 'C'
update_date datetime
-- no table constraints really, outside of name_audit_id as PK
)
триггер базы данных А создается, который заполняет NAME_AUDIT
каждый раз, что-либо сделано к NAME
. Таким образом, у Вас есть запись каждого изменения, внесенного в таблицу, и когда. Приложение не имеет никакого реального знания этого, так как оно сохраняется триггером базы данных.
Это работает обоснованно хорошо и не требует, чтобы любые изменения в коде приложения реализовали.
Я думаю, что предпочитаю добавлять метки времени к отдельным таблицам. Присоединение на Вашей таблице метки времени на составном ключе - один из которых является строкой - будет медленнее и если у Вас будет большой объем данных, то это в конечном счете будет настоящая проблема.
кроме того, много времени при рассмотрении меток времени это - когда Вы отладите проблему в своем приложении, и Вы захотите данные тут же, вместо того, чтобы всегда иметь необходимость присоединиться против другой таблицы.
Преимущество метода, который Вы предлагаете, состоит в том, что он дает Вам опцию добавления других полей к Вашей таблице TIMESTAMP, как отслеживание пользователя, который внес изменение. Можно ли также отследить редактирования к чувствительным полям, например, кто повторно оценил этот контракт?
Регистрирующиеся рекордные изменения в отдельном файле означают, что можно показать несколько изменений в записи, как:
mm/dd/yy hh:mm:ss Добавленный XXX mm/dd/yy hh:mm:ss Полевая ЦЕНА, Измененная XXX, mm/dd/yy hh:mm:ss Запись, удаленная XXX
, Один недостаток является дополнительным кодом, который выполняет желание, вставляет в Вашу таблицу TIMESTAMPS для отражения изменений в основных таблицах.
Если Вы настраиваете материал метки времени для убегания триггеров, чем какое-либо действие, которое может выделить триггер (Чтения?) может быть зарегистрирован. Также могли бы быть некоторые преимущества блокировки.
(Берут все, что с мелкой частицей соли, я не DBA или гуру SQL)
Да, я люблю этот дизайн и использую его с некоторыми системами. Обычно, некоторый вариант:
LogID int
Action varchar(1) -- ADDED (A)/UPDATED (U)/DELETED (D)
UserID varchar(20) -- UserID of culprit :)
Timestamp datetime -- Date/Time
TableName varchar(50) -- Table Name or Stored Procedure ran
UniqueID int -- Unique ID of record acted upon
Notes varchar(1000) -- Other notes Stored Procedure or Application may provide
Один кошмар с Вашим дизайном состоит в том, что каждая вставка, обновление или удаляют, должен был бы поразить ту таблицу. Это может вызвать основную производительность и блокирующие проблемы. Это - плохая идея обобщить таблицу как этот (не только для меток времени). Это также был бы кошмар для получения данных из.
, Если Ваш код повредился бы на уровне GUI от добавляющих полей, Вы не хотите, чтобы пользователь видел, Вы неправильно пишете код к своему GUI, который должен указать только минимальное число столбцов, в которых Вы нуждаетесь и никогда не выбираете *.
Я думаю дополнительные соединения, которые необходимо будет выполнить для получения, Метки времени будут небольшим хитом производительности и болью шея. Кроме этого я не вижу проблемы.
Мы сделали точно, что Вы сделали. Это является большим для объектной модели и способности добавить новые штампы и различные типы штампов к нашей модели с минимальным кодом. Мы также отслеживали пользователя, который внес изменение, и большая наша логика в большой степени была основана на этих штампах. Разбуженный очень хорошо.
Один недостаток сообщает и/или показывает много различных штампов на на экране. При выполнении его способ, которым мы сделали это, это вызвало много соединений. Кроме того, назад окончание изменяется, была боль.
Наше решение состоит в том, чтобы поддержать таблицу "Transaction", в дополнение к нашей таблице "Session". ОБНОВЛЕНИЕ, ВСТАВЬТЕ и УДАЛИТЕ инструкции, все управляются через объект "Транзакции" и каждый из этих, инструкция SQL хранится в таблице "Transaction", после того как это было успешно выполнено на базе данных. Эта таблица "Transaction" имеет другие поля, такие как transactiontType (я для ВСТАВКИ, D для УДАЛЯЮ, U для ОБНОВЛЕНИЯ), transactionDateTime, и т.д., и внешний ключ "sessionId", говоря нам наконец, кто отправил инструкцию. Даже возможно через некоторый код, определить, кто сделал, какой и когда (Gus создал запись в понедельник, Tim изменил Цену за единицу товара во вторник, Liz добавила особую скидку в четверг, и т.д.).
Профессионалы для этого решения:
Недостатки,
Наш выбор: все записи, более старые, чем 90 дней, автоматически удаляются каждое утро
Philippe,
просто не удаляют более старых, чем 90 дней, перемещают их сначала в отдельный DB или пишут им в текстовый файл, сделайте что-то для сохранения их, просто переместите их из основного производства DB.
, Если когда-нибудь сводится к нему, чаще всего это - случай "его с большинством побед документации"!