|
|
|
Дерево. Большое и сложное. Как?
|
|||
|---|---|---|---|
|
#18+
Нужно выбрать в таблицу упорядоченное дерево из таблиц с данными. Данные представлены так: "Родительский номер" | "Свой номер" Надо получить такое: "Уровень" | "Свой номер" выглядит примерно так: Уров | номер 0001 | 1243123252345 0002 | 2343342602834 0002 | 2356223904745 0003 | 1357000478453 0002 | 2343495872457 0001 | 2343495872457 0001 | 2343495872200 0002 | 2324564560896 0003 | 2343000763447 0004 | 2343243472457 0004 | 2345788211122 0002 | 2343495874557 Думаю понятно. Таблица с данными большая (пол миллиона записей) результат может достигать 30 уровней вложенности и 200-250 тыс строк. Ркурсивной функцией. если проходить по каждому элементу получается очень долго. Может кто предложит другой алгоритм. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.09.2002, 10:21:26 |
|
||
|
Дерево. Большое и сложное. Как?
|
|||
|---|---|---|---|
|
#18+
Классическая реализация деревьев, при которой в таблице хранится ID родителя, имеет ряд существенных недостатков, в числе которых и один самый существенный - невозможность ‘раскрутить’ дерево в одном запросе. Схема Joe Celko также имеет ряд ограничений (например, сложности с изменением родителя у какой-либо ветки среднего уровня). Предлагаемый мной механизм лишен этого, а также многих других недостатков, хотя требует дополнительного места в БД. Основой механизма является таблица следующей структуры (пример дерева отделов-Departments): Таблица TreeDepartments Название поля/Назначение/Ключ/индекс DepID/Идентификатор/Форейн на Departments&Первичный ключ + кластерный индекс ParentDep/ Идентификатор родителя / Форейн на Departments Level/ Уровень относительно корня ParentLevel/ Уровень родителя относительно корня Т.е. в этой таблице описываются все родственные отношения в дереве. Таким образом, для того, чтобы получить набор записей, содержащий фрагмент дерева, подчиненный какому-либо ID, достаточно выбрать из таблицы TreeDepartments все записи с ParentDep, равным этому ID. Для того, чтобы получить всех детей первого уровня достаточно добавить условие Level = ParentLevel+1. В принципе, при такой организации дерева просто реализовываются практически любые фантазии относительно получения фрагментов дерева или информации о родителях. Недостатком такой организации является необходимость ее поддержки, т.е. содержание данных таблицы TreeDepartments в актуальном состоянии. Один из вариантов – реализация на триггерах таблицы Departments. Т.е. при изменении данных в таблице Departments, добавляются/удаляются соответствующие записи в таблице TreeDepartments. Ниже приводится рабочий скрипт, который на базе существующей таблицы Departments создаст вышеописанные таблицы и триггера, а также инициализирует таблицу, заполнив ее на основании существующих данных. Единственным условием является Null в поле ParentDep у всех ROOTов таблицы Departments. Триггера выполняют все необходимые действия для того, чтобы работа с деревом была абсолютно прозрачной. Триггер на добавление вставляет необходимый набор записей в таблицу Departments, ориентируясь по ParentDep всавленных записей, триггер на удаление соответственно удаляет все неактуальные записи из TreeDepartments, а триггер на обновление меняет родителей в TreeDepartments. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. 130. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. 144. 145. 146. 147. 148. 149. 150. 151. 152. 153. 154. 155. 156. 157. 158. 159. 160. 161. 162. 163. 164. 165. 166. 167. 168. 169. 170. 171. 172. 173. 174. 175. 176. 177. 178. 179. 180. 181. 182. 183. 184. 185. 186. 187. 188. 189. 190. 191. 192. 193. 194. 195. 196. 197. 198. 199. 200. 201. 202. 203. 204. 205. 206. 207. 208. 209. 210. 211. 212. 213. 214. 215. 216. 217. 218. 219. 220. 221. 222. 223. 224. 225. 226. 227. 228. 229. 230. 231. 232. 233. 234. 235. 236. 237. 238. 239. 240. 241. 242. 243. 244. 245. 246. 247. 248. 249. 250. 251. 252. 253. 254. 255. 256. 257. 258. 259. 260. 261. 262. 263. 264. 265. 266. 267. 268. 269. 270. 271. 272. 273. 274. 275. 276. 277. 278. 279. 280. 281. 282. 283. 284. 285. 286. 287. 288. 289. 290. 291. 292. 293. 294. 295. 296. 297. 298. 299. 300. 301. 302. 303. 304. 305. 306. 307. 308. 309. 310. 311. 312. 313. 314. 315. 316. 317. 318. 319. 320. 321. 322. 323. 324. 325. 326. 327. 328. 329. 330. 331. 332. 333. 334. 335. 336. 337. 338. 339. 340. 341. 342. 343. 344. 345. 346. 347. 348. 349. 350. 351. 352. 353. 354. 355. 356. 357. 358. 359. 360. 361. 362. 363. 364. 365. 366. 367. 368. 369. 370. 371. 372. 373. 374. 375. 376. 377. 378. 379. 380. 381. 382. 383. 384. 385. 386. 387. 388. 389. 390. 391. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.09.2002, 10:30:39 |
|
||
|
Дерево. Большое и сложное. Как?
|
|||
|---|---|---|---|
|
#18+
Все просто класно описано. Спасибо. Есть только один проблемс. Таблицы с хранимыми данными. Нам дают как есть. Делать с ними я ничего не могу. Надо выбирать из существующей. :( В этом то вся и проблема. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.09.2002, 10:39:31 |
|
||
|
Дерево. Большое и сложное. Как?
|
|||
|---|---|---|---|
|
#18+
Посмотри ответ SergSuper от 24 июля 2002 11:29\r \r /topic/10197 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.09.2002, 10:43:25 |
|
||
|
Дерево. Большое и сложное. Как?
|
|||
|---|---|---|---|
|
#18+
Так исходная таблица абсолютно не меняется. Просто добавляется еще одна. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.09.2002, 10:47:38 |
|
||
|
Дерево. Большое и сложное. Как?
|
|||
|---|---|---|---|
|
#18+
2Tulkin Эта схема замечательная, и не тяжёлая для сервера, однако в ней есть большой недостаток - не обеспечивается необходимая сортировка. Если в доп. таблице держать и её, то тогда обновление станет проблемой. 2Lesorub Ещё год назад здесь был предложен достаточно эффективный метод запроса поддерева: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.09.2002, 11:15:12 |
|
||
|
Дерево. Большое и сложное. Как?
|
|||
|---|---|---|---|
|
#18+
2 alexeyvg А что ты понимаешь под обеспечением необходимой сортировки? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.09.2002, 11:23:47 |
|
||
|
Дерево. Большое и сложное. Как?
|
|||
|---|---|---|---|
|
#18+
2Tulkin Вывод дерева в том порядке, в котором он виден на экране. Это актуально, например, для веб-приложений - можно из рекордсета тупо генерить хэ-тэ-мэ-эль; например: исходное дерево: ID ParentID level name 1 null 0 Rasha 2 1 1 Piter 3 1 1 Moscow 4 1 1 Xabarovsk 5 3 2 Tverskaya 6 3 2 Leninskyi Вывод с сортировкой: ID ParentID level name 1 null 0 Rasha 3 1 1 Moscow 5 3 2 Tverskaya 6 3 2 Leninskyi 2 1 1 Piter 4 1 1 Xabarovsk ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.09.2002, 13:15:09 |
|
||
|
Дерево. Большое и сложное. Как?
|
|||
|---|---|---|---|
|
#18+
Все варианты которые я смотрел - довольно не плохие. У меня у самого есть 2 работающих варианта - один шустро но нет структуры (выбирет все варианты которые с ним связаны) и медленный - рекурсивный. Зато строит красивое дерево и все что надо учитывает. Проблема еще заключается в том что из полученных данных придется уитавать возможность отбрасывания НЕ ПОСЛЕДНИХ элементов. последние элементы могут быть на любом уровне и в любом порядке. Мне кажется что ни один вариант пока из мною просмотренных не дает возможности сделать такой анализ без дополнительного запроса по каждому элементу на принадлежность его к КОНЦУ (запрос узнает есть ли такой номер в родительском поле.) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.09.2002, 14:09:05 |
|
||
|
Дерево. Большое и сложное. Как?
|
|||
|---|---|---|---|
|
#18+
сделать это можно так - с использованием временной таблицы. здесь TABLENAME - таблица из которой необходимо сделать выборку. структура таблицы ID int OwnerID int Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.09.2002, 12:38:31 |
|
||
|
|

start [/forum/topic.php?fid=46&msg=32049298&tid=1820311]: |
0ms |
get settings: |
7ms |
get forum list: |
13ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
43ms |
get topic data: |
7ms |
get forum data: |
2ms |
get page messages: |
39ms |
get tp. blocked users: |
1ms |
| others: | 204ms |
| total: | 322ms |

| 0 / 0 |
