我有一个客户表,其中包含有关客户偏好的信息,例如他是否希望收到简报等等。如果他/她想要收到简报,则该值存储在“customerNewsletter”列中并设置为true。但是,我有一些这些位值和参数位于自己的列中。我为每个客户存储日期,真/假,整数和tekst。
我发现大约80%的客户希望收到简报,这使得80%的价值设置为真。我现在将每个客户设置的值存储为false或true。如果我只需要将20%设置存储为假,该怎么办?
有一个列表,其中包含大约20个这样的参数,我可以将它们作为一个列(它们现在是),但我想知道是否有更好的方法。
所以我创建了3个表来保存这些参数值,一个保存实际值的参数表,一个保存值的名称的paramsNames表和一个将参数连接到customerID的参数表
SELECT
customerParamsName as [Name],
customerParamText as [Text],
customerParamINT as [int],
customerParamsDateTime as [Date]
FROM db14.customerParams
INNER JOIN db14.customerParam ON customerParamsChildID = customerParamID
INNER JOIN db14.customerParamsNames ON customerParamNameID = customerParamsNameID
这会给我
Name Text int Date
Phonenumber NULL 615164898 2013-09-20 00:00:00.000
有人能告诉我这是不是一个好方法,还是有更常见的方法来更有效地存储多类型参数?
我创建了2个表
customerParam
paramID paramNameID ParamParentID paramChildID paramText paramINT paramDate
INT TINYINT INT INT varchar(24) INT DATETIME
PRIMARY INDEXED
customerParamNames
paramNameID paramName
TINYINT VARCHAR(24)
PRIMARY
1 'FirstName'
2 'LastName'
3 'Email Address'
4 'Phonenumber'
5 etc..
假设我想存储firstName和LastName
我在customerParam中为两个值创建记录;
paramID paramNameID ParamParentID paramChildID paramText paramINT paramDate
17456 1 'John'
17467 2 'Doo'
17468 1 752 17456
17469 2 752 17467
由于我希望更多出现名称'John',我将其存储为独立值,然后使用parentID / ChildID组合加入它。
和phoneNumber
17470 4 752 31615164899
17471 5 752 'me@here.com'
对于这个客户来说,phonenumber是非常明确的,我使用parentID将其直接加入到客户手中。电子邮件地址也是如此。
此时此解决方案看起来像是要走的路......我还在看xml方法,但我对如何使用存储在数据库中的XQuery和xmlDocuments没有很好的理解。 而且似乎有很多开销。
我将继续推进上述解决方案......直到有人给我一个更好的解决方案。
示例SQL
DECLARE @paramNames TABLE (paramNameID TINYINT, paramName varchar(24))
DECLARE @param TABLE (paramID INT, paramNameID TINYINT, paramParentID INT, paramChildID INT, paramText varchar(24), paramINT INT, paramDate datetime)
INSERT INTO @paramNames VALUES ( 1, 'firstname')
INSERT INTO @paramNames VALUES ( 2, 'lastname')
INSERT INTO @paramNames VALUES ( 3, 'emailaddress')
INSERT INTO @paramNames VALUES ( 4, 'phonenumber')
select * from @paramNames
INSERT INTO @param VALUES (1, 1, Null, Null, 'John' , Null, Null)
INSERT INTO @param VALUES (2, 2, Null, Null, 'Doo' , Null, Null)
INSERT INTO @param VALUES (3, 1, 752, 1, Null , Null, Null)
INSERT INTO @param VALUES (4, 2, 752, 2, Null , Null, Null)
INSERT INTO @param VALUES (5, 4, 752, Null, Null , 615164899, Null)
INSERT INTO @param VALUES (5, 3, 752, Null, 'me@here.com' , Null, Null)
select
a.paramParentID, b.paramName, c.paramText, c.paramINT, c.paramDate
from @param a
inner join @paramNames b on a.paramNameID = b.paramNameID
inner join @param c on a.paramChildID = c.paramID
UNION ALL
select
a.paramParentID, b.paramName, a.paramText, a.paramINT, a.paramDate
from @param a
inner join @paramNames b on a.paramNameID = b.paramNameID
WHERE paramParentID IS NOT NULL
AND paramChildID IS NULL
给出结果
paramParentID paramName paramText paramINT paramDate
752 firstname John NULL NULL
752 lastname Doo NULL NULL
752 phonenumber NULL 615164899 NULL
752 emailaddress me@here.com NULL NULL
答案 0 :(得分:2)
如果您考虑到性能和灵活性,我会稍微改变一下。
USE Test;
CREATE TABLE Customers
(
CustomerID INT NOT NULL CONSTRAINT PK_Customers
PRIMARY KEY CLUSTERED IDENTITY(1,1)
, CustomerName NVARCHAR(255)
);
CREATE TABLE CustomersReceivingEmails
(
CustomerID INT NOT NULL CONSTRAINT FK_CustomerID
FOREIGN KEY REFERENCES Customers (CustomerID)
ON DELETE CASCADE ON UPDATE CASCADE
, EmailAddress NVARCHAR(255) NOT NULL
CONSTRAINT PK_CustomersReceivingEmails
PRIMARY KEY CLUSTERED (CustomerID, EmailAddress)
);
INSERT INTO Customers (CustomerName) VALUES ('Max');
INSERT INTO Customers (CustomerName) VALUES ('Mike');
INSERT INTO CustomersReceivingEmails (CustomerID, EmailAddress)
VALUES (1, 'us@them.com');
INSERT INTO CustomersReceivingEmails (CustomerID, EmailAddress)
VALUES (1, 'us@me.com');
/* ALL Customers */
SELECT * FROM Customers;
/* Only customers who wish to receive Emails, allows a given customer
to have multiple email addresses */
SELECT C.CustomerName, E.EmailAddress
FROM Customers C
INNER JOIN CustomersReceivingEmails E ON C.CustomerID = E.CustomerID
ORDER BY C.CustomerName, E.EmailAddress;
SELECT
返回如下行:
这允许Customers
表包含所有客户,无论他们对电子邮件的偏好如何。
对于想要接收电子邮件的客户,CustomersReceivingEmails
表格有Customers.CustomerID
的外键。
答案 1 :(得分:1)
您的第二个解决方案是通常所说的Entity-Attribute-Value数据模型的变体。这种方法似乎很灵活。但是,它本质上在模式中生成模式,并且随着属性数量的增加而查询非常慢
如果您要存储大量相同的值,请查看columnstore indexes。它们在选择性较低的情况下很好地工作(许多行和只有少量不同的值)