如何在SQL数据库中存储业务活动?

如何在SQL数据库中存储业务活动?,sql,android-activity,history,Sql,Android Activity,History,目标是存储插入、更新和删除业务记录等活动 我正在考虑的一个解决方案是对每个要跟踪的记录使用一个表。以下是一个简化的示例: CREATE TABLE ActivityTypes ( TypeId int IDENTITY(1,1) NOT NULL, TypeName nvarchar(50) NOT NULL, CONSTRAINT PK_ActivityTypes PR

目标是存储插入、更新和删除业务记录等活动

我正在考虑的一个解决方案是对每个要跟踪的记录使用一个表。以下是一个简化的示例:

CREATE TABLE ActivityTypes
(
    TypeId              int IDENTITY(1,1)       NOT NULL,
    TypeName            nvarchar(50)            NOT NULL,

    CONSTRAINT PK_ActivityTypes          PRIMARY KEY (TypeId),
    CONSTRAINT UK_ActivityTypes          UNIQUE (TypeName)
)

INSERT INTO ActivityTypes (TypeName) VALUES ('WidgetRotated');
INSERT INTO ActivityTypes (TypeName) VALUES ('WidgetFlipped');
INSERT INTO ActivityTypes (TypeName) VALUES ('DingBatPushed');
INSERT INTO ActivityTypes (TypeName) VALUES ('ButtonAddedToDingBat');

CREATE TABLE Activities
(
    ActivityId          int IDENTITY(1,1)       NOT NULL,
    TypeId              int                     NOT NULL,
    AccountId           int                     NOT NULL,
    TimeStamp           datetime                NOT NULL,

    CONSTRAINT PK_Activities                      PRIMARY KEY (ActivityId),
    CONSTRAINT FK_Activities_ActivityTypes        FOREIGN KEY (TypeId)
                                                  REFERENCES ActivityTypes (TypeId),
    CONSTRAINT FK_Activities_Accounts             FOREIGN KEY (AccountId)
                                                  REFERENCES Accounts (AccountId)
)

CREATE TABLE WidgetActivities
(
    ActivityId          int                     NOT NULL,
    WidgetId            int                     NOT NULL,

    CONSTRAINT PK_WidgetActivities                  PRIMARY KEY (ActivityId),
    CONSTRAINT FK_WidgetActivities_Activities       FOREIGN KEY (ActivityId)
                                                    REFERENCES Activities (ActivityId),
    CONSTRAINT FK_WidgetActivities_Widgets          FOREIGN KEY (WidgetId)
                                                    REFERENCES Widgets (WidgetId)
)

CREATE TABLE DingBatActivities
(
    ActivityId          int                     NOT NULL,
    DingBatId           int                     NOT NULL,
    ButtonId            int,

    CONSTRAINT PK_DingBatActivities                  PRIMARY KEY (ActivityId),
    CONSTRAINT FK_DingBatActivities_Activities       FOREIGN KEY (ActivityId)
                                                     REFERENCES Activities (ActivityId),
    CONSTRAINT FK_DingBatActivities_DingBats         FOREIGN KEY (DingBatId)
                                                     REFERENCES DingBats (DingBatId)
    CONSTRAINT FK_DingBatActivities_Buttons          FOREIGN KEY (ButtonId)
                                                     REFERENCES Buttons (ButtonId)
)
此解决方案似乎适合于获取给定小部件或dingbat记录id的所有活动,但对于获取所有活动,然后尝试确定它们引用的记录,则不太合适

也就是说,在本例中,所有帐户名和时间戳都存储在一个单独的表中,因此很容易创建以用户和时间间隔为重点的报告,而不需要知道具体的活动是什么

但是,如果您确实希望特别按类型报告活动,则此解决方案需要确定常规活动表所指的活动类型

我可以将我所有的活动类型放在一个表中,但是ID不能被外键约束,相反,表名可以用作ID,这将导致我使用动态查询

请注意,在示例中,dingbat活动有一个可选的按钮Id。如果按钮名称在添加到dingbat后被编辑,则该活动将能够引用该按钮并知道其名称,因此如果报告按dingbat和按按钮名称列出所有活动,按钮名称的更改将自动反映在活动描述中


正在寻找一些其他想法,以及这些想法如何在编程工作、数据完整性、性能和报告灵活性之间折衷。

SQL日志如何?

SQL日志如何?

我将冒险猜测一下您真正想要实现的目标

您说您正在尝试跟踪“门店活动”,我假设您有以下活动: 购买新物品 出售物品 注销项目 雇佣员工 工资雇员 解雇员工 更新员工记录

好的,对于这些活动,您需要几个不同的表:一个用于库存,一个用于部门,一个用于员工

库存表可能包含以下信息:

inventory:
  item_id (pk)
  description (varchar)
  number_in_stock (number)
  cost_wholesale (number)
  retail_price (number)
  dept_id (fk)

department:
  dept_id (pk)
  description (varchar)

employee
  emp_id (pk)
  first_name (varchar)
  last_name (varchar)
  salary (number)
  hire_date (date)
  fire_date (date)
因此,当您购买新项目时,您将更新库存表中的库存数量,或者创建一个新行(如果它是您以前从未拥有过的项目)。当你出售一件物品时,你会将该物品的库存数量递减(也适用于注销物品时)

雇用新员工时,将他们的记录添加到employees表中。当你向他们付款时,你从薪水栏中获取他们的薪水。当你解雇他们时,你会填写该栏作为他们的记录(并停止支付他们)


在所有这些操作中,这些操作不是由数据库完成的。SQL应该用于跟踪信息。可以编写执行这些更新的过程(更新发票记录中所有项目的新发票过程)。但是你不需要一张桌子来做事情。事实上,一张桌子什么也做不了


在设计数据库时,您需要问的问题不是“我需要做什么?”而是“我需要跟踪哪些信息?”

我将不遗余力地猜测一下您真正想要实现的目标

您说您正在尝试跟踪“门店活动”,我假设您有以下活动: 购买新物品 出售物品 注销项目 雇佣员工 工资雇员 解雇员工 更新员工记录

好的,对于这些活动,您需要几个不同的表:一个用于库存,一个用于部门,一个用于员工

库存表可能包含以下信息:

inventory:
  item_id (pk)
  description (varchar)
  number_in_stock (number)
  cost_wholesale (number)
  retail_price (number)
  dept_id (fk)

department:
  dept_id (pk)
  description (varchar)

employee
  emp_id (pk)
  first_name (varchar)
  last_name (varchar)
  salary (number)
  hire_date (date)
  fire_date (date)
因此,当您购买新项目时,您将更新库存表中的库存数量,或者创建一个新行(如果它是您以前从未拥有过的项目)。当你出售一件物品时,你会将该物品的库存数量递减(也适用于注销物品时)

雇用新员工时,将他们的记录添加到employees表中。当你向他们付款时,你从薪水栏中获取他们的薪水。当你解雇他们时,你会填写该栏作为他们的记录(并停止支付他们)


在所有这些操作中,这些操作不是由数据库完成的。SQL应该用于跟踪信息。可以编写执行这些更新的过程(更新发票记录中所有项目的新发票过程)。但是你不需要一张桌子来做事情。事实上,一张桌子什么也做不了


在设计数据库时,您需要问的问题不是“我需要做什么?”而是“我需要跟踪哪些信息?”

基于对问题的不同解释的新答案

你只是想把发生的事情列个清单吗?如果您只需要过去事件的有序列表,则只需要一个表:

action_list
  action_list_id (pk)
  action_desc (varchar)

event_log:
  event_log_id (pk)
  event_time (timestamp)
  action_list_id (fk)
  new_action_added (fk)
  action_details_or_description (varchar)
在这种情况下,操作列表类似于:

1   'WidgetRotated'
2   'WidgetFlipped'
3   'DingBatPushed'
4   'AddNewAction'
5   'DeleteExistingAction'
事件日志将是发生了什么活动以及何时发生的列表。您的其中一个操作是“添加新操作”,并要求在所采取的操作为“添加新操作”时,在事件表中填写“添加新操作”列

您可以创建更新、删除、添加等操作

编辑: 我在事件中添加了action\u details\u或\u description列。通过这种方式,您可以提供有关操作的更多信息。例如,如果您有“产品更改颜色”操作,则新颜色的描述可能为“红色”


更广泛地说,您需要提前考虑并规划所有不同类型的操作,以便您可以以一种能够准确包含要放入表中的数据的方式设置表

新答案,基于对问题的不同解释

你只是想把发生的事情列个清单吗?如果你只需要一个p的有序列表
CREATE TABLE Object_Activities
(
     activity_id     INT          NOT NULL,
     object_id       INT          NOT NULL,
     activity_type   INT          NOT NULL,
     activity_time   DATETIME     NOT NULL,
     account_id      INT          NOT NULL,
     CONSTRAINT PK_Object_Activities PRIMARY KEY CLUSTERED (activity_id),
     CONSTRAINT FK_Object_Activities_Objects
     FOREIGN KEY (object_id) REFERENCES Objects (object_id),
     CONSTRAINT FK_Object_Activities_Activity_Types
     FOREIGN KEY (activity_type) REFERENCES Activity_Types (activity_type),
)

CREATE TABLE Dingbat_Activities
(
     activity_id     INT     NOT NULL,
     button_id       INT     NOT NULL,
     CONSTRAINT PK_Dingbat_Activities PRIMARY KEY CLUSTERED (activity_id),
     CONSTRAINT FK_Dingbat_Activities_Object_Activities
     FOREIGN KEY (activity_id) REFERENCES Object_Activities (activity_id),
     CONSTRAINT FK_Dingbat_Activities_Buttons
     FOREIGN KEY (button_id) REFERENCES Object_Activities (button_id),
)