下圖是依照Entity繼承結構所產生的Physical Data Schema。經過詳細檢視後,發現這個設計會無法Insert資料。因為E_SupportingPerson和Organization的entityID是不同的值。這樣E_TeleComIndex的entityID值無法同時參照Organization及E_SupportingPerson的entityID。因此無法work。現在要考慮怎麼解決這個問題
下圖是依照Entity繼承結構所產生的Physical Data Schema。經過詳細檢視後,發現這個設計會無法Insert資料。因為E_SupportingPerson和Organization的entityID是不同的值。這樣E_TeleComIndex的entityID值無法同時參照Organization及E_SupportingPerson的entityID。因此無法work。現在要考慮怎麼解決這個問題
下圖為原本規劃的Observation結構,此結構依照資料型態是Integer、Decimal、及String來將資料放在不同的表格中。這樣的設計方式會導致查詢及Insert資料時都變得很困難
以下說明在這樣的設計下,Query及Insert資料會有多複雜
1、查詢某個病人的血糖數據
Step1:取得符合檢驗數據的actID
SELECT A_Act.actID FROM A_Act,P_Particiaption_Subject,R_Patient,E_Person
WHERE E_Person.entityID = R_Patient.entityID AND
R_Patient.roleID = P_Participation_Subject.roleID AND
A_Act.actID = P_Participation_Subject.actID AND
A_Act.classCode = 'OBS'
Step2:由Observation類別取得實際檢驗值
SELECT resultValue,resultCaptureDatetime from A_ObservationInteger
WHERE resultTitle = 'BloodSugar' UNION
SELECT resultValue,resultCaptureDatetime from A_ObservationDecimal
WHERE resultTitle = 'BloodSugar' UNION
SELECT resultValue,resultCaptureDatetime from A_ObservationString
WHERE resultTitle = 'BloodSugar'
上述的Query並不假設BloodSugar存放在ObservationInteger或ObservationString表格中,這樣的查詢
也比較容易撰寫。
要注意的是,在Insert資料時,BloodSugar只能Insert到ObservationDecimal中,而何種檢驗數據要放在那個表格,可記錄在另一Meta_ObservationTile表格中
=============================================
2. Insert某病人的檢驗報告,內含10種檢驗數據
Step1: 建立一筆新資料到A_Act表格
INSERT INTO A_Act (actID,classCode,moodCode)
VALUES (<actID>,'OBS','EVN')
Step2: 查詢Meta_ObservationTitle表格,得到那些數據要放到那些表格
SELECT observationTitle, recordTable from Meta_ObservationTile
WHERE observationTitle in ('BloodSugar','BodyWeight','...')
Step3: 以一個While迴圈去iterate Step2的SQL回傳值。針對每一筆回傳值,將資料Insert到相對應表格,下面以BloodSugar為例,假設查詢結果顯示BloodSugar應該放在A_ObservationDecimal
INSERT INTO A_ObservationDecimal (obsTitle,obsValue,obsCaptureDatetime,actID,code,obsUnit)
VALUES ('BloodSugar',100.2,20100623110102,<actID>,'checkType','mg/dl')
Step4: 等迴圈處理完畢後,Commit
Step5: 在E_Person中,檢查entityID是否已存在,若不存在則Create新的一筆E_Person Record
Step6: 查詢該E_Person實體的entityID有沒有Play病人的Role,若沒有則Create新的一筆R_Patient實體
SELECT R_Role.roleID FROM E_Person,R_Patient,R_Role
WHERE E_Person.entityID = R_Patient.entityID AND
R_Patient.roleID = R_Role.roleID AND
R_Role.classCode = 'PAT'
Step7: 將actID與roleID更新到P_Participation_Subject中
INSERT INTO P_Participation_Subject (actID,roleID,typeCode)
VALUES (<actID>,<roleID>,'SBJ')
Step8: Commit
為了簡化Insert及Update的動作,與Liangzhou討論過後,決定要將原本依照不同資料型態而分成不同表格的Observation,合併成一個Observation table。合併後結果如下圖
Query及Insert資料的步驟如下
1、查詢某個病人的血糖數據
Step1:取得符合檢驗數據的actID
SELECT A_Act.actID FROM A_Act,P_Particiaption_Subject,R_Patient,E_Person
WHERE E_Person.entityID = R_Patient.entityID AND
R_Patient.roleID = P_Participation_Subject.roleID AND
A_Act.actID = P_Participation_Subject.actID AND
A_Act.classCode = 'OBS'
Step2:由Observation類別取得實際檢驗值
SELECT obsIntegerValue,obsDecimalValue,obsStringValue,resultCaptureDatetime from A_Observation
WHERE resultTitle = 'BloodSugar'
在回傳值中,obsIntegerValue,obsDecimalValue和obsStringValue應該只會有一個有值,程式必需進行判斷。
也可以建立一個Meta_ObservationTile表格,記錄什麼檢驗數據是什麼資料型態。然後程式先查詢該Meta table,得知要查詢Integer、Decimal還是String
2. Insert某病人的檢驗報告,內含10種檢驗數據
Step1: 建立一筆新資料到A_Act表格
INSERT INTO A_Act (actID,classCode,moodCode)
VALUES (<actID>,'OBS','EVN')
Step2: 查詢Meta_ObservationTitle表格,得到那些數據要放到那些表格
SELECT observationTitle, recordTable from Meta_ObservationTile
WHERE observationTitle in ('BloodSugar','BodyWeight','...')
Step3: 以一個While迴圈去iterate Step2的SQL回傳值。針對每一筆回傳值,將資料Insert到A_Observation的相對應欄位,下面以BloodSugar為例,假設查詢結果顯示BloodSugar應該放在obsDecimalValue欄位中
INSERT INTO A_Observation (obsTitle,obsDecimalValue,obsCaptureDatetime,actID,code,obsUnit)
VALUES ('BloodSugar',100.2,20100623110102,<actID>,'checkType','mg/dl')
Step4: 等迴圈處理完畢後,Commit
Step5: 在E_Person中,檢查entityID是否已存在,若不存在則Create新的一筆E_Person Record
Step6: 查詢該E_Person實體的entityID有沒有Play病人的Role,若沒有則Create新的一筆R_Patient實體
SELECT R_Role.roleID FROM E_Person,R_Patient,R_Role
WHERE E_Person.entityID = R_Patient.entityID AND
R_Patient.roleID = R_Role.roleID AND
R_Role.classCode = 'PAT'
Step7: 將actID與roleID更新到P_Participation_Subject中
INSERT INTO P_Participation_Subject (actID,roleID,typeCode)
VALUES (<actID>,<roleID>,'SBJ')
Step8: Commit
這樣的修改對於減化Query的幫助較大,而對於減化Insert的幫助較為有限。不過至少可以讓整個data model較容易了解
typeCode=PRD,描述Supply與食物(material)的關係。
typeCode=RCT,描述Pateint與該Supply的關係。
利用這樣,可以用一個Act.id把飲食與Patient串起來
以下的敘述描述RIM六大class中的四大class之間的關係。
用一句話來說明就是 Entity 會 扮演Role;所扮演的Role會去Participate某個Act
[Entity] ---play--->[Role]--->[Participate]--->[Act]
參考:PWR Schema Design Decision:盡量限制PWR的繼承關係至多為三層
二個禮拜前,覺得想要把繼承關係限制為三層,現在覺得應該直接限制成二層,目前正在測試這樣的架構有沒有問題
扁平他繼承關係的手段:
1.直接將子子類別繼承自父類別
這裡舉Act、Supply、Diet的關係為例子,下面第一個圖是依據RIM的結構,Act、Supply和Diet的關係。但是這樣的設計方式,會沒辦法塞資料。比方說,現在要塞diet的資料,它的classCode是”Diet”,若依照下面的設計,要塞Diet就一定要塞資料到Supply。但是Supply的classCode是SPLY,如果塞進去的話,就會違反RIM的設計。若把A_Diet接到A_Act下面,似乎就可以解決這樣的問題了
修改後的結構如下,若來源資料的classCode是SPLY,就將資料塞到A_Supply中;若classCode是A_Diet,就將資料塞到A_Diet中。注意因為A_Diet是繼承自A_Supply,所以要記得將原本A_Supply有的屬性也複製一份到A_Diet中
2.用association取代繼承
2010/06/22
依照儘量減少不需要的屬性以及分散繼承關係屬性的原則,決定將Observation類別的屬性做下列處置
經過屬性的修改後,發現Observation看起來像是一個多餘的類別,依照儘量減少繼承階層數目的原則。決定將Observation與其子類別進行整併。下圖為原始的類別關係圖
下圖為整併後的類別關係圖
得到這樣的關係圖後,接下來討論這些檢驗數據如何分類放置。目前因為不管如何進行分類都有其缺點。這裡先決定以撰寫資料輸入程式的方便性為較高的考量。依照這樣的概念,依實際的情境,將會一起出現的資料放在同一表格。然後再用view將同一個檢驗數值再結合起來呈現。比方說血糖資訊可能來自遠端監控,也可能來自醫院的檢驗。為了處理方便,就先將這兩個來源的資料放置在不同表格中。然後最後再用個view取得所有血糖的資料。這樣分類方式,需提供一個設計以確保未來extend時,資料的完整性
參考:PWR Schema Design Decision:拆開或合併 有繼承關係Entity的決定因素
PWR Schema Design Decision:盡量限制PWR的繼承關係至多為三層
本篇文章顯示合併或分拆Entity取捨中,較為複雜的例子。 下圖為原始的Entity關係圖
因為在上圖中,Procedure只有Surgery及SubstanceAdministration兩個子Entity,該兩個Entity在PWR中會引用的概念上有比較大的差異。且Surgery與Procedure的概念上比較相近,因此決定將Surgery併到Procedure,然後SubstanceAdministration直接繼承自Act。經過修改後的Model如下
參考:PWR Schema Design Decision:盡量限制PWR的繼承關係至多為三層
將Entity拆成多個子Entity:
優點:擴充性較高,新增別種子型別的Entity時,對於父Entity的影響不大。
缺點:填入資料及查詢資料的程式較為複雜,且繼承關係愈長,UOW愈長,為了要檢查RI的完整性,可能會導致較多的Lock
將多個子Entity併回一個父Entity:
優點:填入資料及查詢資料的程式較為簡單,一個SQL即可完成交易,UOW較短
缺點:在新增別種子型別Entity時,擴充性較低
因為分拆與合併的優缺點是相互抵觸的,所以在這裡定下一個標準:只有針對PWR主要Focus且有彈性擴充需求相關資料,如Remote monitoring的資料,採用分拆的設計;其它次要的資料及較無彈性擴充需求的相關資料,如醫療記錄、生活史資料,則採用合併的設計
Act.repeatNumber的資料型態為IVL(Interval);Act.effectiveTime資料型態為時間。將這兩個值併入Frequency meta-table即可表示頻率資訊。如下圖
不過因為effectiveTime的資料型態為TS,而Frequency所需要的時間是elapse Time,所以再將Frequency entity更改為下圖。用elapseTimeUnit來代表是elpase time的單位是年、周、月、日;然後用elapseTimeQty來表示elapse time的數目
Reference:PWR Schema Design Decision:如何分散繼承關係中的屬性?
依照儘量減少不需要的屬性以及分散繼承關係屬性的原則,決定將Act類別的屬性做下列處置
| classCode:保留以維持semantic,且此值會做為insert資料時,決定將資料填入那個子table的依據 moodCode:保留以維持semantic code:移除,依照此說明,Act.code是optional的欄位,只是作為specialize classCode之用 title:移到子類別,為非必需欄位,且將title值放置在子類別的欄位可以讓該值更有意義 text:移到子類別,為非必需欄位,與title一樣,text值移至此類別欄位,可讓該值更有意義 statusCode:移到子類別。為非必需欄位,只有特殊子類別才需要利用statusCode描述Act的狀態 effectiveTime:移到子類別。為非必需欄位,且將此值放置在子類別的欄位可以讓該值更有意義 activityTime:移到子類別。為非必需欄位,且將此值放置在子類別的欄位可以讓該值更有意義 availabilityTime:移到子類別。為非必需欄位,且將此值放置在子類別的欄位可以讓該值更有意義 priorityCode:移到子類別。只有少數子類別可能需要此值 confidentialityCode:保留,可用來決定是否可Query此Act的資料 repeatNumber: 移除。為非必需欄位,目前還沒想到有何用處 interruptibleInd:移除。為非必需欄位,目前還沒想到有何用處 levelCode: 移除。為非必需欄位,只是作為標示該Act子類別位於繼承關係的第幾層。且在新版RIM可能被移除 IndependentInd:移除。為非必需欄位。用來標示可否直接對該Act進行排序之類的操作。 uncertaintyCode:移到子類別。為非必需欄位。用來標示該Act所描述的事實的可信度。 reasonCode:移除。目前發現只有patientEncounter有需要使用到reason這個概念,但是目前沒有把它變成Code的需求,直接用純文件記錄即可 languageCode:移到子類別。用以描述Act.text所使用的語言 |
EncapsulatedData (ED): Data that is primarily intended for human interpretation or for further machine processing outside the scope of HL7.
ConceptDescriptor (CD):A reference to a concept defined in a code system
CodedSimpleValue (CS):Coded data in its simplest form, where only the code is not predetermined. The code system and code system version are fixed by the context in which CS value occurs. CS is used for coded attributes that have a single HL7-defined value set.
Interval (IVL):A set of consecutive values of an ordered base data type.
Boolean (BL): A binary value for use in boolean logic. A BL value can be either true or false, or, as any other value, MAY be NULL.
CNE(Code without Exception):取代CE這個Datatype,不可extent原本的coding
CWE(Code With Exception):也是取代CE這個Datatype,可以extend原本的coding
PWR的資料來源可能有CDA及Web UI兩大類,本文章探討如何設計Schema,以簡化處理這兩種資料的程式之設計
------------To Be Done----------
在此篇PWR Schema Design Decision:如何在有繼承關係的類別階層中Insert data文章中,討論到在Insert一筆資料到有繼承關係的表格時,為了要維持資料的Integrity,必需透過classCode,循著繼承關係,在一層一層的表格中填入資料,若階層關係很長,不但將來在撰寫資料Insert程式會很困難,也容易造成Commit的時間太長而導致Lock的情況發生。因此決定PWR將儘量限制其繼承關係為3層
移除的方法為詳細檢視該繼承之關係,檢討是否需要這麼多class,若實際上不需這麼多層的關係,可以將要刪除的class中的屬性移到其它繼承樹的其它class後,再將class刪除
下圖為一個繼承的Entity階層關係,表示Diet這個Entity是繼承自Supply;而Supply又是繼承自Act。也就是說Diet IsA Supply,且Supply IsA Act。因此,某一個Diet的Instance的actID值,必需在Supply及Act的actID欄位找得到。
為了確保這樣的資料一致性,在Insert資料時,應該依照下列順序進行:
Insert into Act,把需要的資料輸入完畢後,檢查classCode為何,若classCode為SPLY,則知道還要再在Supply表格上輸入相對應資料。若classCode為DIET,則知道還需要在Diet中輸入資料,輸入完之後,還要再Update Supply這個資料的表格內容。等到這些表格都更新完後,才能進行Commit
為了確保將來資料更新程式的正確性,應該要提供一個meta-table,來描述classCode與應更新的表格名稱之間的關係
依照此篇文章:PWR Schema Design Decision:如何分散繼承關係中的屬性?所探討,在處理RIM繼承的狀況時,儘量將父類別的屬性搬移到此類別,除非該屬性在父類別已具備完整的定義。那麼,在將父類別的屬性搬移至子類別後,能否將其更名呢?目前的想法是可以將其更名,原因如下:
在更名完畢後,使用RDA在該更名過後屬性的Documentation一欄處,輸入它對應於那個父類別的那個屬性。如此一來,在產生DDL時,RDA會將此資訊加到產生的資料庫欄位的註解中,提供有興趣了解該欄位對應至那個HL7類別的屬性的人進行查找
本文章討論,在進行PWR設計時,在一個繼承的關係中,父類別中的屬性是要分散到子類別中,還是存放在父類別中
上圖所示的是一個RIM Model片斷的表示方式,在上圖的例子中,父類別擁有最多的屬性。這樣的設計其實並不恰當,應該儘量將屬性搬移至子類別,論點如下:
修正後的結構類似下圖(p.s.為了簡化,下圖只是示意圖)
看準開放式平台 硬體商組軟體公司
2010/06/03 17:41 中央社
(中央社記者周品均台北2010年6月3日電)開放式平台Android、,MeeGo作業系統在本次台北國際電腦展大放異彩,安謀 (ARM)、德州儀器 (TI)、IBM等公司今天宣布成立新軟體公司LINARO,預計將在11月推出軟體開發工具。
仔細觀看本屆國際電腦展,各大電腦廠除了展出搭載微軟 (Microsoft)作業系統外,也紛紛推出搭載Android作業系統的小筆電、平板產品,顯示開放式平台Linux的興起,雖然微軟仍在市占率上遠遠領先,Lunix卻也逐步進攻。
看準開放式平台Linux的後市,ARM、飛思卡爾(Freescale)、IBM、三星 (Samsung)、德州儀器、ST-Ericsson等6家硬體廠商今天宣布成立軟體公司LINARO,並由Tom Lantzsch出任執行長,未來將不以營利為目標。
Tom Lantzsch表示,以成立公司方式,投入經費研發鍵接系統晶片與作業系統的開發工具,而非選擇贊助Linux團體經費進行研發的原因在於,公司具有較好的執行力,研發時間與進度都較容易掌握。
實際上,LINARO更像是一個基金會,Tom Lantzsch表示,LINARO初期將由6家公司提供經費與研發人力,進行軟體研究、開發,同時將持續開放讓各廠商加入,是一不限制成員的組織。
ARM指出,硬體廠商要將諸如Android、MeeGo、LiMo等作業系統搭載在硬體裝置上時,仍要花費許多研發成本,因此,成立軟體公司,就是要聚集各家大廠的力量,減少重覆研發的資源浪費,未來公司成員也都可以受惠於研發結果。990603
資料來源:http://emrstd.doh.gov.tw/emr/trainning/DocLib/6_RMIM.pptx
R-MIM是由D-MIM所挑出來用於某個特別情境的class的集合,其表示方式不是使用UML,而是使用其私有的獨特表達方式。以下簡單整理在RMIM這種獨特表達方式中所使用到的notation
每個RMIM只會有一個Entry point來連繫到所要focus的焦點或主題,被指向的焦點對應到實際的XML文件中,它就是該XML文件的Root element。下圖為Entry Point notation的解讀方式
對應回CDA RMIM為例子,它的Entry Point的R-MIM/CMET Name就是 CDA R-MIM、R-MIM/CMET Identifier就是POCD_RM000040
如下圖所示,Class的顏色是有意義的,顏色代表該class是由那一個RIM的核心Class “clone”出來的。每個Clone出來的class都會有個Clone Name,也會有classCode、moodCode這些與RIM結構有關的attribute。依據HL7的wiki說明(連結),Clone Name只是在由RIM “clone”出 class時,資料塑模人員給定的一個名字,它本身並沒有任何Semantic的功能。RIM的Semantic是保留在clone出來的class的 classCode、moodCode、typeCode…等結構性的attributes中。因此在作運算時,應該是拿classCode這類結構性的attribute來做,而不是clone name。不過資料塑模人員需要儘量取與classCode、moodCode這些attribute所代表的語意相近的名稱作為Clone Name,以便讀取該Model的人員,能很快地理解該class所代表意義,而不需去查classCode等這些attribute值的意義
Role用來標示Entity和Entity之間的關係。所以它會連結到兩個Entity,與其中的一個Entity的連線為實線(Playing),表示該Entity Play這個角色;與另一個Entity的連線為虛線(Scoping),表示被連結的Entity知道、或被assign到該role。
其它的三個類別為Relationship相關的類別都是採用箭頭的方式來標示
當在某個情況下,可以取用多個不同Class的選擇時,可以用Choice的標示方法,來表示有那些Class可供選擇使用
出處:http://www.ncbi.nlm.nih.gov/pmc/articles/PMC1380194/
這篇文章對於CDA的設計有較整體性的介紹,以下摘錄個人認為比較有趣的地方
CDA是一個文件架構的標準,使用XML技術,將醫療資訊塑模至XML文件之中。塑模的過程中,CDA R2整份文件都採用了HL7 V3的RIM模型,以及HL7 V3的Data type(不像CDA R1只有針對Header的部分採用了RIM模型)。CDA的文件可分成Header及Body兩部分,其中Header的部分的功能是標示此文件的種類,並提供Authentication、Encounter、Patient及提供醫療服務的Provider的資訊。而Clinical Report的部分則都是放在Body的部分。放在Body中的資訊可以是Structured的資訊,也可以是Un-Structured的資訊。也因為如此,Body部分是CDA文件中,最具彈性,也最複雜的地方。
上圖為CDA RMIM擷取下來的片斷,若Body的部分放置結構化的資訊,則每種結構化的資訊都要放在Section這個元件之內。如上圖所示,除了一些結構化的屬性(如classCode及moodCode之外),Section還有一些屬性可以用來描述每個Section元素內包含的內容為何。
Section.id: 為每個Section提供一個Unique的編碼
Section.code: 標示此要放在Section的臨床資料的種類,如Chief complaint(病患主訴)、allergy或adverse reaction…等。這些code的值就是一些編碼系統,如LONIC或SNOMED的編碼值
Section.title: 標示此Section的名稱,此名稱必需為Human readable
Section.text: 將narrative block形式的Clinical資訊(所謂narrative block即為human readable的格式)
在放置Section資料時,若要精準到Level3(computer computable)的層次的話,則在Section內還會再多一個Entry。因為包含的是computer computable資訊,所以每個item都需使用編碼。下圖為該paper舉的一個簡單的Observation範例
對於複雜的事實,有可能需要描述多個不同Act子物件的關係,此時就可以使用RIM的ActRelationship來詳加描述。下圖為paper舉的一個使用ActRelationship關係來描述病患家族史的例子
下表則為ActRelationship可能的relaiton type