2

我正在设计一个数据库,我有一个关于如何将一些用户数据设为私有的问题。

我有一个用户表,其中包含姓名、城市、生日、传记等。用户可以将一些数据设为私有(其他用户可以看到该数据)。

首先,我想向表中添加列以指示列是否是私有的。例如:

User
-------

user_id  | name | city | cityIsPrivate | birthday | birthdayIsPrivate
---------+------+------+---------------+----------+------------------

或者,另一种方法是添加一个 varchar 列来指示哪些列是私有的:

User
-------

user_id  | name | city | birthday | privateColumns
---------+------+------+----------+---------------

而这个 privateColumns 将有这个:"city:NO; birthday:YES"

用户表将只有三列可以是私有的或公共的。我只需要在表格中再添加三列。

有什么建议吗?

4

3 回答 3

3

如果每次查询主表时都必须将数据加入到单独的表中,请不要将其移动到单独的表中。

布尔(或等效)列,用于指示可以应用隐私设置的每一列的隐私:

  1. 添加非常简单。
  2. 几乎不占用空间。
  3. 查询起来要快得多。
  4. 表明隐私设置是用户数据的固有部分。
  5. 从架构中消除不必要的复杂性。

这些与其他列相关并且它们代表一种逻辑对象的事实只是一种干扰。追求简单性、性能和逻辑正确性。

于 2013-10-18T07:47:31.387 回答
1

您可以有一个单独的表(例如 UserPrivateFields)列出用户 ID 以及他们选择设为私有的字段,如下所示:

UserID | PrivateField
-------+-------------
1      | Name
1      | City
2      | Birthday

当您运行获取用户信息以由请求信息的人拉取的过程时,您可以构建这样的查询(假设所需用户的 UserID 被传递到 proc 中):

CREATE TABLE #PublicUserFields (Publicfield varchar(50))
INSERT INTO #PublicUserFields (Publicfield)
SELECT Publicfield
FROM userPublicfields
WHERE userid = @userid

Declare @sql VARCHAR(MAX) = 'SELECT '
WHILE EXISTS (SELECT 1 FROM #PublicUserFields)
BEGIN
    DECLARE @Publicfield VARCHAR(50) = 
        (SELECT TOP 1 Publicfield FROM #PublicUserFields)
    SET @sql = @SQL + @Publicfield
    IF (SELECT COUNT(*) FROM #PublicUSERFIELDS) > 1
    BEGIN
        SET @SQL = @SQL + ', '
    END

    DELETE FROM #PublicUserFields 
    WHERE Publicfield = @Publicfield
END

SET @SQL = @SQL + ' FROM MainTable WHERE userID = @userID'

EXEC(@SQL)

我对动态 SQL 感到困扰的原因是,您的公共字段的名称无法通过此设置直接连接到主表的列- 它们只能被选择或连接到具有相同字符串值的其他记录. 您可以通过加入 sys.columns 并使用列的 object_id 做一些有趣的事情来解决这个问题,但这似乎并不比这种方法容易得多。

如果用户都可以动态设置他们希望其他人可以查看的字段,那么这是有道理的。如果私有字段是已知的并且是静态的,您可能只想将这两个类别分开并收紧私有表的读取权限。

于 2013-10-18T07:05:26.463 回答
1

将您的私有列列表移动到包含三个字段的单独表中,例如:

UserId |ColumnName |IsPrivate
-----------------------------

然后,您可以将您的查询与该表连接起来,并为每个用户获取正确的结果集,同时更改您的用户表的列。

如果您的用户表不认为有更改,最好将您的私有列列表移动到具有适当结构的单独表中,如下所示:

UserId |cityIsPrivate |birthdayIsPrivate
----------------------------------------

然后,您可以在单个查询中将您的用户表与该表连接起来,并获得您需要的结果集。

但不要放在同一张桌子上。第一种方法为您的数据库结构带来了冗余。在第二种情况下,您将无法通过 IsPrivate 标准进行 SELECT 查询。

于 2013-10-18T06:51:27.280 回答