我正在设计一个数据库,我有一个关于如何将某些用户数据设为私有的问题。
我有一个用户表,其中包含姓名、城市、生日、传记等。并且用户可以将一些数据设为私有(其他用户可以看到该数据)。
首先,我想向表中添加列来指示列是否是私有的。例如:
User
-------
user_id | name | city | cityIsPrivate | birthday | birthdayIsPrivate
---------+------+------+---------------+----------+------------------
或者,另一种方法是添加一个 varchar 列来指示哪些列是私有的:
User
-------
user_id | name | city | birthday | privateColumns
---------+------+------+----------+---------------
这个 privateColumns 将具有以下内容:
"city:NO; birthday:YES"
。
用户表只有三列,可以是私有的或公共的。我只需在表格中再添加三列即可。
有什么建议吗?
如果每次查询主表时都必须连接数据,请勿将数据移动到单独的表中。
布尔(或等效)列,用于指示可以应用隐私设置的每个列的隐私:
这些与其他列相关并且它们代表单一类型的逻辑对象这一事实只是一种干扰。追求简单、性能和逻辑正确性。
将私有列的列表移动到具有三个字段的单独表中,例如:
UserId |ColumnName |IsPrivate
-----------------------------
然后,您可以将查询与该表连接起来,并为每个用户获取正确的结果集,同时更改用户表的列。
如果您的用户表不会发生更改,最好将私有列列表移动到具有正确结构的单独表中,如下所示:
UserId |cityIsPrivate |birthdayIsPrivate
----------------------------------------
然后您可以在单个查询中将您的用户表与此表连接起来并获得您需要的结果集。
但不要放在同一张桌子上。第一种方法为数据库结构带来冗余。在第二种情况下,您将无法通过 IsPrivate 标准进行 SELECT 查询。
您可以有一个单独的表(例如 UserPrivateFields),列出用户 ID 以及他们选择设为私有的字段,如下所示:
UserID | PrivateField
-------+-------------
1 | Name
1 | City
2 | Birthday
当您运行获取要由请求信息的人提取的用户信息的过程时,您可以构建如下查询(假设所需用户的 UserID 已传递到过程中):
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 感到困扰的原因是,通过此设置,公共字段的名称无法直接连接到主表的 names 列 - 它们只能通过以下方式选择或连接到其他记录:相同的字符串值。您也许可以通过加入 sys.columns 并使用列的 object_id 做一些有趣的事情来解决这个问题,但这似乎并不比这个方法容易得多。
如果用户都可以动态设置他们希望其他人可以查看哪些字段,那么这是有意义的。如果私有字段是已知的并且是静态的,您可能只想将这两个类别分开并收紧对私有表的读取访问权限。
我更喜欢在应用程序中管理私有和公共字段,原因如下: