存储ID数组以及如何在选择中正确解压缩它们

时间:2018-06-08 13:54:00

标签: postgresql

这可能部分是一个设计问题(PostgreSQL的新功能)。

我有三个表 - Users,Groups和User_Group。 User_Group表示链接到0..X组ID的1个user_id的组合。

表格就像你想象的那样简单(现在,建立这个东西):

用户:ID,姓名,....

群组:ID,姓名,...

User_Group :UserID,GroupID int [],...

现在,User_Group中的GroupID字段是一个Integer数组。例如,UserID 1的值为{1,2,10,19,28}。

目标: 在我的UI中,我需要将该列表表示为组名(即:{Group1,Group2,Group10,Group19,Group28})。

所以,因为我是PostgreSQL的新手,我正在研究并且有一些想法浮现在我脑海中 - 不需要,任何和阵列替换。所有尖叫性能问题给我,但我可能是错的(这是设计问题,存储数组是否聪明?)

我的查询:

select 
    u.*,
    g.group_ids
from users u
left join user_group g
    on u.id = g.user_id

我想弄清楚如何进入:

select ug.group_id 
from (select unnest(group_ids) group_id FROM user_group) as ug
left join groups g 
    on g.id = ug.group_id

这将导致(显然)与该人员相关联的每个组ID的附加行。

这是最好的方法吗?

2 个答案:

答案 0 :(得分:0)

(就个人而言,我会将Users表上的一列作为Groups(int数组),但您的选择也很好)。

它看起来像(我使用了我的头顶上的表和字段名称,比你的略有修改):

select u.*, g.Name as GroupName
from users u
left join usergroups ug on ug.UserId = u.UserId
left join groups g on g.groupId = ANY( ug.groups );

更新:我可能误解了你的需要。也许你是这个意思:

select u.*, 
  (select string_agg(g.name,',') 
   from groups g 
   inner join usergroups ug on ug.groupId = g.GroupId
   where ug.UserId = u.UserID and 
         g.groupId = ANY( ug.groups )) as Groups
from users u;

答案 1 :(得分:0)

在那里,你有一对多的关系:

用户(1) - >(*)群组

这种关系不需要用于链接定义的中间表。一对多关系用于在子表中使用外键(在本例中为Groups)。

结果将是:

  • 用户:id,name
  • 组:id,name,user_id
  • 您可以将约束添加到数据库中:if ("FirstTime".equals(new SharedPrefsOperations(this).getPreferencesData("ActiveNotifs"))) { // I AM EXECUTING THIS ONLY AT FIRST TIME , WHEN THE FIRST NOTIFICATION ARRIVES. String tempData = new SharedPrefsOperations(this).getPreferencesData("ActiveNotifs"); Notification notification = new NotificationCompat.Builder(this, "MYAPP") .setSmallIcon(R.mipmap.ic_static_notif) .setContentTitle(content.getTitle()) .setContentText(tempMsg) .setAutoCancel(true) .setContentIntent(pendingIntent) .setGroup(notifGroup) .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)) .setChannelId(channel_id) .setStyle(inboxStyle) .setGroupSummary(true) .build(); notificationManager.notify(id, notification); new SharedPrefsOperations(this).storePreferencesData("ActiveNotifs", "1"); } else { // I AM EXECUTING THIS FROM SECOND NOTIFICATION ONWARDS String tempData = new SharedPrefsOperations(this).getPreferencesData("ActiveNotifs"); Notification notification = new NotificationCompat.Builder(this, "MYAPP") .setSmallIcon(R.mipmap.ic_static_notif) .setContentTitle(content.getTitle()) .setContentText(tempMsg) .setAutoCancel(true) .setContentIntent(pendingIntent) .setGroup(notifGroup) .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)) .setChannelId(channel_id) .setStyle(inboxStyle) .build(); notificationManager.notify(id, notification); new SharedPrefsOperations(this).storePreferencesData("ActiveNotifs", "1"); }