Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 在SQL Server中存储详细数据_Sql Server_Database Design - Fatal编程技术网

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