Если вам нужна быстрая скорость чтения, лучшим вариантом является использование таблицы закрытия. Таблица закрытия содержит строку для каждой пары предков / потомков. Итак, в вашем примере таблица закрытия будет выглядеть как
ancestor | descendant | depth
0 | 0 | 0
0 | 19 | 1
0 | 20 | 2
0 | 21 | 3
0 | 22 | 4
19 | 19 | 0
19 | 20 | 1
19 | 21 | 3
19 | 22 | 4
20 | 20 | 0
20 | 21 | 1
20 | 22 | 2
21 | 21 | 0
21 | 22 | 1
22 | 22 | 0
. После того, как у вас есть эта таблица, иерархические запросы становятся очень легкими и быстрыми. Чтобы получить всех потомков категории 20:
SELECT cat.* FROM categories_closure AS cl
INNER JOIN categories AS cat ON cat.id = cl.descendant
WHERE cl.ancestor = 20 AND cl.depth > 0
Конечно, существует большой недостаток, когда вы используете денормализованные данные, подобные этому. Вам нужно поддерживать таблицу закрытия рядом с таблицей категорий. Лучший способ, вероятно, использовать триггеры, но несколько сложно правильно отслеживать вставки / обновления / удаления для таблиц закрытия.
Редактирование: см. Вопрос Какие существуют варианты хранения иерархических данных в реляционной базе данных?
g0] для получения дополнительных опций. Существуют различные оптимальные решения для разных ситуаций.
Сначала нужно проверить совпадение, а затем использовать группы. Т.е.
match()
совпадения только в начало строки, т. е. с неявным ^
якорем search()
совпадает в любом месте строки # works with Python 2 and Python 3
import re
with open('dummy.txt', 'r') as fh:
for rec in fh:
orec = ' rec: >' + rec.rstrip('\n') + '<'
print(orec)
match = re.match(r'XA([0-9]+)=(.*?[^#])!', rec)
if match:
(index, dvalue) = match.groups()
print(" index = >{}< value = >{}<".format(index, dvalue))
continue
match = re.match(r'PZ([0-9]+)=(.*?[^#])!', rec)
if match:
(index, dvalue) = match.groups()
print(" index = >{}< value = >{}<".format(index, dvalue))
continue
print(" Unknown Record format")
Вывод:
$ python dummy.py
rec: >DUD=ABC!QUEUE=D23!<
Unknown Record format
rec: >XA32=7!P^=32!<
index = >32< value = >7<
rec: >PZ112=123^!PQ=ABC!<
index = >112< value = >123^<
Но Мне интересно, почему вы не упрощаете свой Perl & amp; код Python просто использовать один регулярное выражение, вместо этого? E.g.:
match = re.match(r'(?:XA|PZ)([0-9]+)=(.*?[^#])!', rec)
if match:
(index, dvalue) = match.groups()
print(" index = >{}< value = >{}<".format(index, dvalue))
else:
print(" Unknown Record format")