У меня небольшая проблема с запросом php mysql, я ищу помощь.
У меня есть таблица древовидного дерева, где я храню для каждого человека его / ее предки id, разделенные запятой. вот так
id ancestors 10 1,3,4,5
Таким образом, человек из 10-ти человек отрождается идентификатором 5, который родился 4-м отцом, который родился 3 и т. Д. …
Теперь я хочу выбрать всех людей, у которых есть id x у своих предков, поэтому запрос будет примерно таким: select * от людей, где такие предки, как «% x%»,
Теперь это будет отлично, если только id x не говорит 2, а запись имеет идентификатор 32 предка, этот запрос будет извлекать 32, потому что 32 содержит 2. И если я использую «%, x,%» (включая запятые) запрос будет игнорировать записи, чей предк x находится на любом краю (влево или вправо) столбца. Он также будет игнорировать записи, чей х является единственным предком, поскольку никакие запятые не присутствуют.
Короче говоря, мне нужен подобный запрос, который ищет выражение, которое либо окружено запятыми, либо не окружено чем-либо. Или запрос, который получает регулярное выражение при условии, что вокруг нет чисел. И мне это нужно как можно эффективнее (я сосать при написании регулярных выражений)
Спасибо.
Edit: Хорошо, ребята, помогите мне придумать лучшую схему.
Вы не храните свои данные надлежащим образом. В любом случае, если вы все еще хотите использовать эту схему, вы должны использовать FIND_IN_SET вместо LIKE, чтобы избежать нежелательных результатов.
SELECT * FROM mytable WHERE FIND_IN_SET(2, ancestors) <> 0
Вы должны рассмотреть возможность изменения структуры базы данных. Добавить новую таблицу «предки» в базу данных со столбцами:
id id_person ancestor 1 10 1 2 10 3 3 10 4
После использования JOIN-запроса с «WHERE IN» выберите правильные строки.
У вас возникла эта проблема из-за неправильного дизайна базы данных. Первые DB-базы данных, основанные на СУБД, не предназначены для такого рода данных, а на основе диаграмм db скорее всего подходят для такого решения.
если он содержит небольшое количество данных, вы можете использовать mysql, но дизайн все еще не прав, если вы только заботитесь о своем «отце», а затем просто добавляете столбец для человека (или, что когда-либо называете его). если его null – не имеет отца / неизвестного в противном случае – содержит (int) его родителя.
В случае, если вам нужно больше, чем просто отношения «отец», вы можете использовать pivot table
чтобы содержать две связи между людьми, но это не простая задача.
Существует несколько установленных способов хранения иерархических данных в РСУБД. Я нашел это слайд-шоу очень полезным в прошлом:
Модели для иерархического дизайна
Поскольку данные относятся к родословной, и поэтому вы не ожидаете, что это так часто изменится – таблица закрытия может соответствовать счету.
Какую бы модель вы ни выбрали, обязательно осмотритесь и посмотрите, уже ли кто-то ее уже реализовал.
Вы можете сохранить свои значения в виде массива JSON
id | ancestors 10 | {"1","3","4","5"}
и затем запросите следующее:
$query = 'select * from people where ancestors like \'%"x"%\'';
Лучше, конечно, использовать таблицу сопоставления для вашего отношения «многие ко многим»
Вы можете сделать это с помощью регулярного выражения:
SELECT * FROM mytable WHERE name REGEXP ',?(x),?'
где x – искомое значение
DROP TABLE IF EXISTS my_table; CREATE TABLE my_table (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,ancestors VARCHAR(250) NOT NULL ); INSERT INTO my_table VALUES(10,',1,3,4,5'); SELECT * FROM my_table WHERE CONCAT(ancestors,',') LIKE '%,5,%'; +----+-----------+ | id | ancestors | +----+-----------+ | 10 | ,1,3,4,5 | +----+-----------+ SELECT * FROM my_table WHERE CONCAT(ancestors,',') LIKE '%,4,%'; +----+-----------+ | id | ancestors | +----+-----------+ | 10 | ,1,3,4,5 | +----+-----------+