· 6 years ago · Jul 08, 2019, 02:56 PM
1Если задача не требует нахождения заказов пользователя, в которых он сменил номер телефона, то я предложил бы такой вариант:
2
3CREATE TABLE IF NOT EXISTS `orders` (
4 `order_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
5 PRIMARY KEY (`order_id`),
6) ENGINE=InnoDB DEFAULT CHARSET=utf8;
7
8
9DROP TABLE IF EXISTS `phones_to_orders`;
10CREATE TABLE IF NOT EXISTS `phones_to_orders` (
11 `phones_to_orders_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
12 `order_id` int(10) unsigned NOT NULL,
13 `phone_number` varchar(50) NOT NULL,
14 PRIMARY KEY (`phones_to_orders_id`),
15 UNIQUE KEY `order_id_phone_number` (`order_id`,`phone_number`),
16 KEY `order_id` (`order_id`)
17) ENGINE=InnoDB DEFAULT CHARSET=utf8;
18
19
20
21При такой архитектуре мы можем достать все заказы, которые содержат заданный номер телефона с помощью запроса:
22SELECT o.order_id
23FROM phones_to_orders AS p2o
24INNER JOIN orders AS o ON o.order_id = p2o.order_id
25WHERE p2o.phone_number = '8KKKNNNNNNN';
26
27
28Однако, у заказов может быть несколько телефонных номеров и один пользователь может чередовать номера, а в каких то случаях указать сразу несколько:
291 заказ
30 8 999-999-99-99
31
322 заказ
33 8 111-111-11-11
34
353 заказ
36 8 999-999-99-99
37 8 111-111-11-11
38
39
40
41В таком случае мы можем связать первый и второй заказ через третий:
42SELECT DISTINCT o.order_id
43FROM orders AS o
44INNER JOIN phones_to_orders AS p2o ON o.order_id = p2o.order_id
45INNER JOIN (
46 SELECT DISTINCT p2o2.phone_number
47 FROM phones_to_orders AS p2o
48 INNER JOIN phones_to_orders AS p2o2 ON p2o2.order_id = p2o.order_id
49 WHERE p2o.phone_number = '84951234567'
50) AS p ON p.phone_number = p2o.phone_number;
51
52
53Так же мы можем создать еще 2 таблицы: users и phones_to_users. В момент создания заказа искать номер в таблице phones_to_users и при успешном нахождении получать идентификатор пользователя и записывать его в таблицу orders.
54Если пользователь передал несколько телефонных номеров, тогда мы связываем с ним все новые.
55При такой архитектуре мы без проблем определим все заказы пользователя без вложенных запросов:
56
57DROP TABLE IF EXISTS `phones_to_users`;
58CREATE TABLE IF NOT EXISTS `phones_to_users` (
59 `phones_to_users_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
60 `user_id` int(10) unsigned NOT NULL,
61 `phone_number` varchar(50) NOT NULL,
62 PRIMARY KEY (`phones_to_users_id`),
63 UNIQUE KEY `phone_number_user_id` (`phone_number`,`user_id`)
64) ENGINE=InnoDB DEFAULT CHARSET=utf8;
65
66ALTER TABLE `orders`
67 ADD COLUMN `user_id` INT(11) UNSIGNED NOT NULL AFTER `order_id`,
68 ADD INDEX `user_id` (`user_id`);
69
70
71SELECT o.order_id
72FROM phones_to_users AS u
73INNER JOIN orders AS o ON o.user_id = u.user_id
74WHERE u.phone_number = '84951234567'
75
76
77Но, ничего не мешает пользователю сделать следующую схему:
781 заказ
79 8 999-999-99-99
80 8 888-888-88-88
81
822 заказ
83 8 111-111-11-11
84
853 заказ
86 8 888-888-88-88
87
884 заказ
89 8 999-999-99-99
90 8 111-111-11-11
91
92
93В данном случае первый заказ принадлежит пользователю №1, второй пользователю №2, третий пользователю №1.
94В этом случае, в момент оформления заказа №4, я бы связал заказ №2 с первым пользователем.