好的,所以我的主题行不是很具描述性,但这里是场景:
最终用户有法律义务向政府机构提交交易数据。交易包含各种个人和组织的名称和地址。但是,最终用户经常拼错报告的个人和组织的名称,或者他们严重破坏了地址等。
最终用户提交的信息是合法的“文件”,因此收到它的机构不能更改。此外,公众可以查看和搜索交易。当政府机构注意到一个明显的拼写错误或不好的地址时,他们希望以一个已知的良好价值“隐藏”或“掩盖”这个不好的价值。例如,如果最终用户输入'Arnie Schwarzeger',该机构可以用'Arnold Schwarzenegger'替换该名称。查看数据的公众将查看(并搜索)正确的拼写,但可以查看最终用户在找到相关数据记录后输入的原始数据。
希望能够很好地解释业务案例......在SQL部分!因此,要解决此问题,我们的表格如下所示:
CREATE TABLE [dbo].[SomeUserEnteredData](
[Id] [uniqueidentifier] NOT NULL,
[LastOrOrganizationName] [nvarchar](350) NOT NULL, // data as entered by end-user
[FirstName] [nvarchar](50) NULL, // data as entered by end-user
[FullName] AS ([dbo].[FullNameValue]([FirstName],[LastName])) PERSISTED, // data as entered by end-user
[MappedName] AS ([dbo].[MappedNameValue]([FirstName],[LastName]))) // this is the 'override' data from the agency
CREATE TABLE [dbo].[CorrectionsByAgency](
[Id] [uniqueidentifier] NOT NULL,
[ReplaceName] [nvarchar](400) NOT NULL,
[KeepName] [nvarchar](400) NOT NULL)
CREATE FUNCTION [dbo].[FullNameValue]
(
@FirstName as NVARCHAR(40),
@LastOrOrganizationName as NVARCHAR(350)
)
RETURNS NVARCHAR(400)
WITH SCHEMABINDING
AS
BEGIN
DECLARE @result NVARCHAR(400)
IF @FirstName = '' OR @FirstName is NULL
SET @result = @LastOrOrganizationName
ELSE
SET @result = @LastOrOrganizationName + ', ' + @FirstName
RETURN @result
END
CREATE FUNCTION [dbo].[MappedNameValue]
(
@FirstName as NVARCHAR(50),
@LastOrOrganizationName as NVARCHAR(350)
)
RETURNS NVARCHAR(400)
AS
BEGIN
DECLARE @result NVARCHAR(400)
DECLARE @FullName NVARCHAR(400)
SET @FullName = dbo.FullNameValue(@FirstName, @LastOrOrganizationName)
SELECT top 1 @result = KeepName from CorrectionsByAgency where ReplaceName = @FullName
if @result is null
SET @result = @FullName
RETURN @result
END
希望如果我的样本不是太复杂,你可以看到,如果代理商输入名称更正,它将替换所有出现拼写错误的名称。从业务逻辑的角度来看,这是完全正确的:代理人员只进行一些更正,并且更正可以覆盖错误名称的所有位置。
从服务器性能的角度来看,这个解决方案是STINKS。无法对计算出的SomeUserEnteredData.MappedName
列建立索引,也无法将从该列读取的视图编入索引!如果我们无法索引MappedName值,那么这对我们的需求无效。
我能够看到的唯一选择是在最终用户创建的数据和代理商创建的数据之间创建一个额外的链接表 - 当代理商输入更正记录时,创建记录每次出现坏列值的链接表。这种情况的不利之处似乎是创建/销毁许多(数十万)链接记录的非常可能的情况,这些记录是由代理机构用户输入的每次更正...
你们中有没有SQL天才对如何解决这个问题有很好的想法?
答案 0 :(得分:1)
我不确定这是否直接回答了您的问题,但我会尝试简化整个过程:停止使用函数,保留“计算”值并使用应用程序逻辑(可能在存储过程中)来管理数据
假设一个代理商更正可以应用于许多用户输入的名称,那么你可以这样:
create table dbo.UserEnteredData (
DocumentId uniqueidentifier not null primary key,
UserEnteredName nvarchar(1000) not null,
CorrectedNameId uniqueidentifier null,
constraint FK_CorrectedNames foreign key (CorrectedNameId)
references dbo.CorrectedNames (CorrectedNameId)
)
create table dbo.CorrectedNames (
CorrectedNameId uniqueidentifier not null primary key,
CorrectedName nvarchar(1000) not null
)
现在,您需要确保您的应用程序逻辑可以执行以下操作:
我假设现实情况相当复杂,并且根据地址和其他数据以及名称进行更正,但您描述的基本关系似乎很简单。正如你所说,这些功能增加了很多开销,而且(对我而言)他们提供的优势不仅仅是直接存储您需要的数据。
最后,我不理解你关于创建/销毁链接记录的评论;由您的应用程序逻辑来正确处理数据更改。