性能考虑:在多个表中分散行与将所有行集中在一个表中。
你好。
我需要在 SQL DB 中记录有关应用程序中进行的每个步骤的信息。有某些表,我希望日志应该与:产品 - 应该在创建产品时记录更改等。订单 - 与上述相同 运输 - 相同等等等等等。
需要经常检索数据。
我对如何做到这一点没有什么想法:
- 有一个包含所有这些表的列的日志表,然后当我想在 UI 中表示某个产品的数据时,会从 Log 中选择 *,其中 LogId = Product.ProductId。我知道有很多列可能会很有趣,但我有这种感觉,性能会更好。另一方面,该表中将有大量行。
- 每种日志类型(ProductLogs、OrderLogs 等)都有很多日志表。我真的不喜欢这个想法,因为它不一致并且有许多具有相同结构的表没有意义,但是(?)搜索时可能会更快在行数较少的表中(我错了吗?)。
- 根据声明没有。1,我可以做第二个多对一表,它将具有 LogId、TableNameId 和 RowId 列,并将日志行引用到数据库中的许多表行,而不是有一个 UDF 来检索数据(例如日志 id 234属于 CustomerId 345 的表 Customer 和 productId = RowId) 的 Product 表;我认为这是最好的方法,但同样,可能会有大量的行,它会减慢搜索速度吗?或者这就是应该怎么做,怎么说?...
上述列表中第 3 位的示例:
CREATE TABLE [dbo].[Log](
[LogId] [int] IDENTITY(1,1) NOT NULL,
[UserId] [int] NULL,
[Description] [varchar](1024) NOT NULL,
CONSTRAINT [PK_Log] PRIMARY KEY CLUSTERED
(
[LogId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Log] WITH CHECK ADD CONSTRAINT [FK_Log_Table] FOREIGN KEY([UserId])
REFERENCES [dbo].[Table] ([TableId])
GO
ALTER TABLE [dbo].[Log] CHECK CONSTRAINT [FK_Log_Table]
---------------------------------------------------------------------
CREATE TABLE [dbo].[LogReference](
[LogId] [int] NOT NULL,
[TableName] [varchar](32) NOT NULL,
[RowId] [int] NOT NULL,
CONSTRAINT [PK_LogReference] PRIMARY KEY CLUSTERED
(
[LogId] ASC,
[TableName] ASC,
[RowId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[LogReference] WITH CHECK ADD CONSTRAINT [FK_LogReference_Log] FOREIGN KEY([LogId])
REFERENCES [dbo].[Log] ([LogId])
GO
ALTER TABLE [dbo].[LogReference] CHECK CONSTRAINT [FK_LogReference_Log]
---------------------------------------------------------------------
CREATE FUNCTION GetLog
(
@TableName varchar(32),
@RowId int
)
RETURNS
@Log TABLE
(
LogId int not null,
UserId int not null,
Description varchar(1024) not null
)
AS
BEGIN
INSERT INTO @Log
SELECT [Log].LogId, [Log].UserId, [Log].Description
FROM [Log] INNER JOIN
LogReference ON [Log].LogId = LogReference.LogId
WHERE (LogReference.TableName = @TableName) AND (LogReference.RowId = @RowId)
RETURN
END
GO