Sql server 在SQL Server中存储详细数据
我正在设计一个保存投票的数据库。 我已经创建了一个表:Sql server 在SQL Server中存储详细数据,sql-server,database-design,Sql Server,Database Design,我正在设计一个保存投票的数据库。 我已经创建了一个表: CREATE TABLE [dbo].[users_votes]( [id] [bigint] NOT NULL, [like_votes] [int] NOT NULL DEFAULT ((0)), [dislike_votes] [int] NOT NULL DEFAULT ((0)), [commented_votes] [int] NOT NULL DEFAULT ((0)), [commen
CREATE TABLE [dbo].[users_votes](
[id] [bigint] NOT NULL,
[like_votes] [int] NOT NULL DEFAULT ((0)),
[dislike_votes] [int] NOT NULL DEFAULT ((0)),
[commented_votes] [int] NOT NULL DEFAULT ((0)),
[comments_likes] [int] NOT NULL DEFAULT ((0))
问题是还需要按位置存储细分数据。
因此,例如,如果user\u vows
表中有1000个特定id的like\u vows
,我需要知道按位置划分的明细,例如:
美国340
法国155
丹麦25
巴西290
澳大利亚190
我以逗号分隔字符串的形式从客户端获取数据,例如:
(1,2,45,67,87112234)和位置的国家代码(美国、澳大利亚、加利福尼亚等)
我一直在考虑存储这些数据的几种可能性,但想知道哪种方法最适合(如果有的话)
users\u vots
表,并为每个标准添加带有国家代码的列。例如,喜欢我们、不喜欢我们、评论我们、评论我们、喜欢我们。
在这种情况下,我可能会使用动态SQL插入/更新数据
的表,如\u voces
,其中我将有一个id、外部\u id
,这将是用户\u voces(表)id、国家\u code
和count
列。因此,数据将存储在users\u voces
和like\u voces
表中。我将为external\u id
和country code
的每种组合记录一次。
在这种情况下,我需要迭代插入的数据,以确定是否存在此外部_id组合(然后只是增加它),或者需要插入它
哪种方法(如果有的话)是存储这些数据的最佳方法,这样可以方便地插入/更新和查询?老实说,目前这种类型的表设计不是一个好主意。构建一个好的关系数据库的一个重要方面是使用范式。我不打算解释这是什么,因为互联网上有成千上万的文章解释它,以及它的不同迭代(从1NF到6NF iirc) 不管怎样,你可以用几张桌子轻松做到这一点。我不得不猜测你在这里的很多设置,但希望你能够推断出你需要什么,并调整不需要的 首先,让我们从一个客户机表开始:
CREATE TABLE dbo.Client (ClientID int IDENTITY(1,1),
ClientName varchar(100), --You should really split this into Title, Forename and Surname, I'm just being "lazy" here
ClientCountryID int, --Not sure if a Client is related to a country or the vote is, i've guessed the client is.
DOB date,
EmailAddress varchar(100));
GO
现在,我们有了一个简单的客户机表。接下来,我们要一张乡村餐桌。这很简单:
CREATE TABLE dbo.Country (CountryID int IDENTITY(1,1),
CountryName varchar(100),
CountryCode char(2)); --For example UK for United Kingdom, FR for France, etc
GO
您可能想在那里存储其他内容,但我不知道您的设置
现在,我真的猜了很多。我假设你的好恶等都与某件事有关。什么,我不知道,所以,我将有一个名为“内容”的表,但是,不知道这些喜欢的东西是反对什么的,我没有这个表的上下文,因此它将是非常基本的:
CREATE TABLE dbo.Content (ContentID int IDENTITY(1,1),
ContentType int, --Guessing might be types, maybe videos, Comments, articles? I have no idea to be honest)
ContentParent int, --Comments are joined to a Content (just like here on SO)? I'll guess it's possible
Content nvarchar(MAX)); --because I have no idea what's going in there
--Very simple Content Type Table
CREATE TABLE dbo.ContentType (TypeID int IDENTITY(1,1),
TypeDescription varchar(100));
GO
现在,我们终于可以得到你想要储存的选票了;可能看起来像这样:
CREATE TABLE dbo.Vote (VoteID int IDENTITY(1,1),
ClientID int,
ContentID int,
Liked bit); --1 for Liked, 0 for Disliked, NULL for N/A perhaps?
GO
好的,现在我们有一些桌子。现在我意识到我没有给出任何类型的样本数据,因此我将为您提供一些INSERT语句,以便您能够了解:
INSERT INTO dbo.Country (CountryName, CountryCode)
VALUES ('United Kingdom','GB'),
('France','FR'),
('Germany','DE');
GO
INSERT INTO dbo.Client (ClientName, ClientCountryID, DOB, EmailAddress)
VALUES ('Mr John Smith',1, '19880106','Bob@gmial.com'),
('Ms Penelope Vert',2,'19930509','PVert@mfn.com');
GO
INSERT INTO dbo.ContentType (TypeDescription)
VALUES ('Video'),('Article'),('Comment');
GO
INSERT INTO dbo.Content (ContentType, ContentParent, Content)
VALUES (2, NULL, 'This is my first article, hi everyone!'),
(3, 1, 'Nice! Good to see you''re finally posting!'),
(1, NULL, 'http://youtube.com');
GO
--And now some votes:
INSERT INTO dbo.Vote (ClientID, ContentID, Liked)
VALUES (1, 1, 1),
(2, 1, 1),
(2, 2, 1),
(2, 3, 0);
GO
注意我是如何投票的。我没有在表中汇总;这样做是个糟糕的主意。而是单独存储每个投票,并使用查询进行聚合。您可以轻松做到这一点,例如:
SELECT C.ContentID,
Cy.CountryName,
COUNT(CASE V.Liked WHEN 1 THEN 1 END) AS LikedVotes,
COUNT(CASE V.Liked WHEN 0 THEN 1 END) AS DisLikedVotes
FROM dbo.Content C
JOIN dbo.Vote V ON C.ContentID = V.ContentID
JOIN dbo.Client CV ON V.ClientID = CV.ClientID
JOIN dbo.Country Cy ON CV.ClientCountryID = Cy.CountryID
GROUP BY C.ContentID,
Cy.CountryName;
这将为您提供每个内容项的喜欢投票数,并为您将其拆分为多个国家/地区。如果您想将这些国家/地区放在自己的列中,那么我强烈建议您在表示层中执行此操作,而不是在SQL中执行此操作(因为您必须使用动态SQL,并且(无意冒犯)根据您当前的数据库设计选择,我想这超出了您的技能范围)。Excel非常擅长使用数据透视表进行此操作。如果希望保留SQL Server中的进程,请考虑使用SSR和矩阵。< /P>
如果你有任何问题,请一定要问
注意:我没有在这里做任何类型的外键、约束、默认值等。对于任何好的数据库设计来说,这些都是必须的
清理脚本:
老实说,你目前的这种桌子设计不是一个好主意。构建一个好的关系数据库的一个重要方面是使用范式。我不打算解释这是什么,因为互联网上有成千上万的文章解释它,以及它的不同迭代(从1NF到6NF iirc) 不管怎样,你可以用几张桌子轻松做到这一点。我不得不猜测你在这里的很多设置,但希望你能够推断出你需要什么,并调整不需要的 首先,让我们从一个客户机表开始:
CREATE TABLE dbo.Client (ClientID int IDENTITY(1,1),
ClientName varchar(100), --You should really split this into Title, Forename and Surname, I'm just being "lazy" here
ClientCountryID int, --Not sure if a Client is related to a country or the vote is, i've guessed the client is.
DOB date,
EmailAddress varchar(100));
GO
现在,我们有了一个简单的客户机表。接下来,我们要一张乡村餐桌。这很简单:
CREATE TABLE dbo.Country (CountryID int IDENTITY(1,1),
CountryName varchar(100),
CountryCode char(2)); --For example UK for United Kingdom, FR for France, etc
GO
您可能想在那里存储其他内容,但我不知道您的设置
现在,我真的猜了很多。我假设你的好恶等都与某件事有关。什么,我不知道,所以,我将有一个名为“内容”的表,但是,不知道这些喜欢的东西是反对什么的,我没有这个表的上下文,因此它将是非常基本的:
CREATE TABLE dbo.Content (ContentID int IDENTITY(1,1),
ContentType int, --Guessing might be types, maybe videos, Comments, articles? I have no idea to be honest)
ContentParent int, --Comments are joined to a Content (just like here on SO)? I'll guess it's possible
Content nvarchar(MAX)); --because I have no idea what's going in there
--Very simple Content Type Table
CREATE TABLE dbo.ContentType (TypeID int IDENTITY(1,1),
TypeDescription varchar(100));
GO
现在,我们终于可以得到你想要储存的选票了;可能看起来像这样:
CREATE TABLE dbo.Vote (VoteID int IDENTITY(1,1),
ClientID int,
ContentID int,
Liked bit); --1 for Liked, 0 for Disliked, NULL for N/A perhaps?
GO
好的,现在我们有一些桌子。现在我意识到我没有给出任何类型的样本数据,因此我将为您提供一些INSERT语句,以便您能够了解:
INSERT INTO dbo.Country (CountryName, CountryCode)
VALUES ('United Kingdom','GB'),
('France','FR'),
('Germany','DE');
GO
INSERT INTO dbo.Client (ClientName, ClientCountryID, DOB, EmailAddress)
VALUES ('Mr John Smith',1, '19880106','Bob@gmial.com'),
('Ms Penelope Vert',2,'19930509','PVert@mfn.com');
GO
INSERT INTO dbo.ContentType (TypeDescription)
VALUES ('Video'),('Article'),('Comment');
GO
INSERT INTO dbo.Content (ContentType, ContentParent, Content)
VALUES (2, NULL, 'This is my first article, hi everyone!'),
(3, 1, 'Nice! Good to see you''re finally posting!'),
(1, NULL, 'http://youtube.com');
GO
--And now some votes:
INSERT INTO dbo.Vote (ClientID, ContentID, Liked)
VALUES (1, 1, 1),
(2, 1, 1),
(2, 2, 1),
(2, 3, 0);
GO
注意我是如何投票的。我没有在表中汇总;这样做是个糟糕的主意。而是单独存储每个投票,并使用查询进行聚合。您可以轻松做到这一点,例如:
SELECT C.ContentID,
Cy.CountryName,
COUNT(CASE V.Liked WHEN 1 THEN 1 END) AS LikedVotes,
COUNT(CASE V.Liked WHEN 0 THEN 1 END) AS DisLikedVotes
FROM dbo.Content C
JOIN dbo.Vote V ON C.ContentID = V.ContentID
JOIN dbo.Client CV ON V.ClientID = CV.ClientID
JOIN dbo.Country Cy ON CV.ClientCountryID = Cy.CountryID
GROUP BY C.ContentID,
Cy.CountryName;
这将为您提供每个内容项的喜欢投票数,并为您将其拆分为多个国家/地区。如果你想把这些国家放在它们自己的列中,那么我strongl