Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Курсовая работа. БД-1

.pdf
Скачиваний:
2
Добавлен:
07.01.2025
Размер:
7.39 Mб
Скачать

 

 

 

11

('example36@email.com',

'1997-09-09',

'{writing,hiking,chess}',

172,

'Hannah', 'Lee', NULL, 'female'),

 

 

('example37@email.com',

'1981-12-24',

'{football,running,gym}',

195,

'Ian', 'Moore', NULL, 'male'),

 

 

('example38@email.com', '2000-03-27', '{painting,singing,gardening}', 167, 'James', 'Nguyen', NULL, 'female'),

('example39@email.com', '1993-06-12', '{music,skiing,dancing}', 187, 'Jasmine', 'Ng', NULL, 'female'),

('example40@email.com', '1976-09-09', '{tennis,swimming,cycling}', 179,

'Jason', 'Peters', NULL, 'male'),

 

 

('example41@email.com',

'1995-12-24',

'{writing,hiking,chess}',

169,

'Katie', 'Williams', NULL, 'female'),

 

 

('example42@email.com',

'1988-03-27',

'{football,running,gym}',

196,

'Leo', 'Mitchell', NULL, 'male'),

 

 

('example43@email.com',

'2001-06-12',

'{music,skiing,dancing}',

188,

'Madison', 'Parker', NULL, 'female'),

 

 

('example44@email.com', '1977-09-09', '{cooking,yoga,photography}', 170, 'Nathan', 'Rogers', NULL, 'male'),

('example45@email.com', '1998-12-24', '{tennis,swimming,cycling}', 191, 'Olivia', 'King', NULL, 'female'),

('example46@email.com', '1984-03-27', '{writing,hiking,chess}', 174, 'Peter', 'Howard', NULL, 'male'),

('example47@email.com', '2003-06-12', '{football,running,gym}', 162, 'Quinn', 'Lee', NULL, 'female'),

('example48@email.com', '1979-09-09', '{painting,singing,gardening}', 186, 'Ryan', 'Nguyen', NULL, 'male'),

('example49@email.com', '1996-12-24', '{music,skiing,dancing}', 178, 'Sophia', 'Peters', NULL, 'female'),

('example50@email.com', '1981-03-27', '{cooking,yoga,photography}', 190, 'Thomas', 'Williams', NULL, 'male'),

('example51@email.com', '2004-06-12', '{tennis,swimming,cycling}', 164, 'Victoria', 'Mitchell', NULL, 'female'),

('example52@email.com', '1976-09-09', '{writing,hiking,chess}', 187, 'William', 'Doe', NULL, 'male'),

('example53@email.com', '1994-12-24', '{football,running,gym}', 171, 'Xavier', 'King', NULL, 'male'),

('example54@email.com', '1991-03-27', '{painting,singing,gardening}', 166, 'Yvonne', 'Ng', NULL, 'female'),

12

('example55@email.com', '1987-06-12', '{music,skiing,dancing}', 193, 'Zachary', 'Parker', NULL, 'male'),

('example56@email.com', '1998-09-09', '{cooking,yoga,photography}', 163, 'Zoe', 'Rogers', NULL, 'female'),

('example57@email.com', '1975-12-24', '{tennis,swimming,cycling}', 184, 'Aaron', 'Howard', NULL, 'male'),

('example58@email.com',

'2001-03-27',

'{writing,hiking,chess}',

177,

'Ava', 'Lee', NULL, 'female'),

 

 

('example59@email.com',

'1982-06-10',

'{football,running,gym}',

194,

'Ben', 'Nguyen', NULL, 'male'),

('example60@email.com', '1996-09-09', '{painting,singing,gardening}', 173, 'Cora', 'Peters', NULL, 'female'),

('example61@email.com', '1978-12-24', '{music,skiing,dancing}', 195, 'Daniel', 'Williams', NULL, 'male'),

('example62@email.com', '2002-03-27', '{cooking,yoga,photography}', 165, 'Emily', 'Mitchell', NULL, 'female'),

('example63@email.com', '1979-06-10', '{tennis,swimming,cycling}', 186, 'Ethan', 'King', NULL, 'male');

Рисунок 2 - Результат выполнения запроса

Теперь необходимо добавить записи в связующую таблицу friends. Некоторые пользователи будут иметь взаимную дружбу, а другие будут числиться как подписчики.

insert into friends(user_id, friend_id) values

(1, 2), (2, 1), (1, 3), (3, 1), (3, 5), (5, 9), (7, 3), (3, 7), (7, 9), (15, 9), (20, 25), (26, 27), (27, 26), (30, 35), (35, 30), (10, 11), (11, 10), (63, 1), (62, 3), (45, 47), (47, 45), (53, 55), (55, 53), (1, 53), (53, 1), (49, 41), (41, 49),(42, 43), (43, 42), (43, 1), (1, 43), (1, 54), (54, 1);

13

1. Вывести список всех друзей одного пользователя select u.* from friends f

inner join friends uf on uf.friend_id = f.user_id and uf.user_id = f.friend_id left join users u on u.id = f.friend_id

where f.user_id = 1;

Рисунок 3 - Результат выполнения запроса на получение друзей пользователя с идентификатором 1

2. Найти самого дружелюбного гуапчича.

select u.id, u.firstname, u.lastname, u.patronymic, count(u.id) as count_friends from friends f

inner join friends uf on uf.friend_id = f.user_id and uf.user_id = f.friend_id

left join users u on u.id = f.user_id

group by u.id, u.firstname, u.lastname, u.patronymic order by count(u.id) desc

limit 1;

Рисунок 4 - Результат выполнения запроса

14 3. Вывести список групп друзей данного человека, с указанием того сколько именно человек состоит в каждой такой группе.

Для начала потребуется добавить данные. Первым делом создадим группы друзей у пользователя:

insert into groups(owner_id, title) values (1, 'relatives'), (1,

'groupmates'), (1, 'colleagues');

Рисунок 5 - Результат выполнения запроса на создание групп

Теперь необходимо распределить тех, у кого с пользователем взаимная дружба - по соответствующим группам.

insert into friend_group(group_id, friend_id) values (1, 54), (2,

43), (2, 53), (1, 3), (1, 2);

Результат выполнения запроса представлен на рисунке 6.

Рисунок 6 - Результат выполнения запроса Запрос на получение распределения друзей пользователя по группам:

select g.title, count(fg.group_id) from groups g left join friend_group fg on fg.group_id = g.id

where g.owner_id = 1

group by g.title, fg.group_id

Результат выполнения запроса представлен на рисунке 7:

15

Рисунок 7 - Распределение друзей пользователя с идентификатора 1 по его группам

4. Найти двух незнакомых жителей с максимальной разницей в росте. Запрос на получение максимальной разницы в росте:

select u1.id, u2.id, abs(abs(u1.height) - abs(u2.height)) diff from users u1

inner join users u2 on u1.id != u2.id

left join friends f1 on f1.user_id = u1.id and f1.friend_id = u2.id left join friends f2 on f2.user_id = u1.id and f2.friend_id = u2.id where f1.user_id is null and f2.user_id is null

order by abs(abs(u1.height) - abs(u2.height)) desc limit 1;

Рисунок 8 - Результат запроса

5. Для каждого пользователя попробовать предложить нескольких других пользователей, которых он возможно захочет добавить в друзья.

16

Запрос можно представить в виде:

SELECT u1.id, u2.id FROM users u1 inner join users u2 on u1.id != u2.id

left join friends f1 on f1.user_id = u1.id and f1.friend_id = u2.id left join friends f2 on f2.user_id = u1.id and f2.friend_id = u2.id

WHERE f1.user_id is null and f2.user_id is null AND u1.hobbies <@ u2.hobbies

AND ABS(DATE_PART('year', u1.date_of_birth) - DATE_PART('year', u2.date_of_birth)) < 5

LIMIT 100;

Таким образом будут отфильтрованы те пользователи, которые между собой знакомы(то есть подписчики или действующие друзья), а затем, на основе хобби и разницы в возрасте не более 5 лет будут отобраны предложения.

Рисунок 9 - Результат выполнения запроса 6. Найти жителя, который создал больше всего групп.

Для начала потребуется добавить данные, по которым затем будет происходить фильтрация. Запрос на добавление имеет вид:

insert into communities (owner_id, title) values

(5, 'Java language'), (6, 'School 71'), (3, 'Training'), (3,

'Humor'),

(3, 'Funny'), (2, 'Autumn'), (2, 'Summer'), (1, 'Winter'), (3, 'Gamers');

17

Запрос на нахождение пользователя, создавшего больше всего групп, имеет вид:

select c.owner_id , count(c.id) from communities c

group by c.owner_id

order by count(c.id) desc

limit 1;

Рисунок 10 - Результат выполнения запроса

7. Найти всех «влиятельных» гуапчичей – таких, что все их друзья состоят хотя бы в одном сообществе, созданным этим «влиятельным» гуапчичем.

Для начала нужно подготовить данные, на основе которых мы будем находить таких пользователей:

insert into communities (owner_id, title) values (1, 'Java

language');

insert into user_community values (3, 7), (3, 1), (10, 2), (8, 3),

(8, 53), (8, 43), (8, 54);

Запрос на получение будет иметь вид: with

friends as (select f.user_id, f.friend_id from friends f

left join friends f2 on f2.friend_id = f.user_id and f2.user_id = f.friend_id where f2.user_id is not null), -- Получаем взаимную дружбу

user_with_communities as (select * from friends f

left join communities c on c.owner_id = f.user_id

left join user_community uc on uc.community_id = c.id

where c.id is not null and uc.participant_id is not null), -- Получаем пользователей с сообществами, у которых есть взаимная дружба

friends_participants as (select uwc.owner_id, array_agg(distinct participant_id) as friends_participants_arr from user_with_communities uwc

18 group by uwc.owner_id), -- Получаем друзей, которые состоят в сообществах

пользователя

user_ids as (select fp.owner_id, array_agg(friend_id = ANY(friends_participants_arr)) from friends_participants fp

left join friends f on f.user_id = fp.owner_id group by owner_id

having false != all(array_agg(friend_id = ANY(friends_participants_arr)))) -- Получаем идентификаторы пользователей, друзьях которых состоят хотя бы в одном из их сообществ select distinct u.* from users u

inner join user_ids ui on ui.owner_id = u.id

Результат выполнения запроса представлен на рисунке 11.

Рисунок 11 - Результат выполнения запроса

8. Найти всех пользователей, у которых есть хобби “running”. Запрос имеет вид:

select * from users where 'running' = any(hobbies)

Рисунок 12 - Результат выполнения запроса

19

9. Найти первые три самых популярных имен среди пользователей Запрос:

select firstname, count(firstname) from users u

group by firstname

order by count(firstname) DESC

limit 3;

Рисунок 13 - Результат выполнения запроса

10. Получить пользователей мужского пола с датой рождения позже 1990-01-01, которые подписаны на сообщества.

Запрос:

SELECT u.firstname, u.lastname, c.title

FROM users u

JOIN user_community uc ON u.id = uc.participant_id

JOIN communities c ON uc.community_id = c.id

WHERE u.date_of_birth >= '1990-01-01' AND u.gender = 'male';

Рисунок 14 - Результат выполнения запроса

20

Пользовательские привилегии

В системе будет четыре роли: бухгалтер-кассир, продюсер, менеджер по персоналу, администратор.

Отдел техподдержки будет доступно содержимого таблицы с пользователями. Модератор будет доступно редактирование таблицы с пользователями(users) и просмотр таблиц friends, communities.

Директор социальной сети будет доступен просмотр всех таблиц. Администратору будут доступны все права.

Создание пользователей(фактически, ролей):

Отдел техподдержки CREATE USER tech_support WITH PASSWORD '123456';

Модератор CREATE USER moderator WITH PASSWORD '123456';

Директор социальной сети CREATE USER director WITH PASSWORD '123456';

Администратор CREATE USER administrator WITH PASSWORD '123456';

Рисунок 15 - Результат заведения пользователей

Для назначения прав административному пользователю можно использовать:

ALTER USER administrator WITH SUPERUSER;