公司產品資料類似這樣
我資料庫規劃這樣 (為了能大找小,小找大)
補充:
大組件可能會共用中組件.小組件,零件...等
老闆說會跑太久,他自己規劃這樣
利用大組件找到中組件,再用中組件一開頭編號分類找到其餘底下小組件或零件
如下圖中組件都是6開頭,則到6開頭資料表找尋更下層
資料量大概大組件共三萬個
公司需求:查詢任何代號可以找到其上下階層關係
想請問 1.老闆方式若要小找大,不是會花更久時間嗎?或是有其他規畫格式,或是有其他搜尋方式
2.最後需樹狀呈現在網頁上,是用4個迴圈寫,感覺會跑很慢(因為目前只用部分資料測試),有其他更好寫法嗎
謝謝
這...不是用外鍵就能做了嗎?
都是一對多。
大類:
id
名稱:
中類:
id
關聯的大類id
名稱:
小類:
id
關聯的中類id
名稱:
要在sql用的話要用遞迴,但是要在django orm的話非常容易...
不過跟php沒關就是。
正常是要用你老闆的觀念。也就是關聯應用的方式處理。
建議採用關聯的方式。
不過的確你的說明並不是很清楚。所以也沒辦法了解你實際真正的需求為何。
就我個人而言。會將資料跟分類(組件)拆開組合
這樣分類好做樹狀處理。
階層TABLE寫法
假設生產料件是用A做成B,用B做成C,用C做成D....依此推
只要建一個TABLE就可以了
生產料件,生產量,使用料件,使用量....其它欄位依自已需求建立
由上述欄位得到此表格(以,區隔--請想像它是表格...)
A,1,B,2 -->生產A一個要用B二個原料或半製品
B,1,C,2 -->生產B一個要用C二個原料或半製品
C,1,D,4 ........
以上為一對一生產BOM表範例
一對多則只是程式上寫法不同,資料表也可用同一個去記錄。
A,1,B1,2
A,1,B2,1
A,1,B3,4.....
如此使用,即可解決您的問題,至於要展到幾階就看貴公司生產BOM表的階數來看了....
當你查A時,系統會帶出A要用B1,B2,B3等原料半製品,再去展出B1要用什麼,只是把B1放在生產料件去看,就會查得您要的資料。
補充一下:至於要順推或反推只是查詢欄位條件設定
遞迴查詢.這個參考資料很多.看你放的標籤ms sql, 應該是用SQL Server, 他有遞迴查詢的功能,
可以試試看. 這是主流. 不懂再來問.
另外
SQL Server 2008 版以後有 hierarchyid data type.
https://docs.microsoft.com/zh-tw/sql/relational-databases/tables/tutorial-using-the-hierarchyid-data-type?view=sql-server-ver15
有一位很久沒出現的Rico , 有寫一篇
https://dotblogs.com.tw/ricochen/2018/06/02/145338
關於這種方式,我在之前有寫一些,有興趣可以參考.
https://ithelp.ithome.com.tw/articles/10227730
https://ithelp.ithome.com.tw/articles/10227989
https://ithelp.ithome.com.tw/articles/10228784
MySQL的話,要8版以後才有遞迴查詢功能. 之前的版本若是要做遞迴查詢,要自己加工.
https://ithelp.ithome.com.tw/questions/10195812
這不就是一般【功能表】的樣式嗎?
殺豬大都已經提出線索啦。
我覺得資料庫規劃不需要用什麼【大組件、中組件、小組件、零件】這樣會受到層次限制,關鍵主鍵應該只有二個欄位,【我本身的id,我的爸爸的id】,不管大找小或小找大,通通適用。
當找到我的id時,同時看看我的爸爸的id是什麼,然後再用爸爸的id,去找他的爸爸id,一直找到沒有爸爸為止。
CREATE TABLE [dbo].[depX] (
[Id] varchar(20) NULL ,
[ParentId] varchar(20) NULL
);
CREATE TABLE [dbo].[product_dtl] (
[productid] varchar(50) NOT NULL ,
[productname] varchar(50) NULL ,
[productspec] varchar(50) NULL
);
SELECT
CONVERT(varchar, DENSE_RANK() OVER (ORDER BY A.Id))+'A' AS level_01,
isnull(A.Id,'*') + isnull(' : ' + dtl_big.productname,'') + isnull(' : ' + dtl_big.productspec,'') as Id_01,
CONVERT(varchar, DENSE_RANK() OVER (ORDER BY A.Id))+'A' + '.' +
CONVERT(varchar, DENSE_RANK() OVER (PARTITION BY A.Id ORDER BY A.Id, B.Id))+'B' AS level_02,
isnull(B.Id,'*') + isnull(' : ' + dtl_medi.productname,'') + isnull(' : ' + dtl_medi.productspec,'') as Id_02,
CONVERT(varchar, DENSE_RANK() OVER (ORDER BY A.Id))+'A' + '.' +
CONVERT(varchar, DENSE_RANK() OVER (PARTITION BY A.Id ORDER BY A.Id, B.Id))+'B' + '.' +
CONVERT(varchar, DENSE_RANK() OVER (PARTITION BY A.Id, B.Id ORDER BY A.Id, B.Id, C.Id))+'C' AS level_03,
isnull(C.Id,'*') + isnull(' : ' + dtl_small.productname,'') + isnull(' : ' + dtl_small.productspec,'') as Id_03
FROM depX AS A
LEFT JOIN depX AS B
ON B.ParentId = A.Id
LEFT JOIN depX AS C
ON C.ParentId = B.Id
LEFT JOIN product_dtl AS dtl_big
ON dtl_big.productId = A.Id
LEFT JOIN product_dtl AS dtl_medi
ON dtl_medi.productId = B.Id
LEFT JOIN product_dtl AS dtl_small
ON dtl_small.productId = C.Id
WHERE 1 = 1
-- 最上層品號 id 的 ParentId =''
AND A.ParentId = ''
ORDER BY A.Id, B.Id, C.Id