2013-08-29 24 views
1

我在MS Access 2013中創建了一個只有一列」長文本「稱之爲備忘錄),並將其作爲表格的主鍵。我存儲了一串長度超過255個字符,然後嘗試存儲另一個字符串,其中前255個字符與先前存儲的字符串相同,但前255個字符後的所有其他字符都不相同,並且MS Access出現「重複數據」錯誤。在新的字符串中,我改變了第255個位置後的字符,使用了不同的字符組合,並且都發生了錯誤。但是當我在第255個位置之前改變任何字符時,它不會給出任何錯誤。因此,我斷定MS Access只檢查「長文本」數據類型的前255個字符,以檢查該列中的重複項。是這樣嗎?還有什麼可能是理由?當它是一個主鍵字段或「索引:是(無重複)允許」時,將長文本/備忘錄字符串截斷爲255個字符「

字符串存儲的256個字符: LoremIpsumissimplydummytextoftheprintingandtypesettingindustryLoremIpsumhasbeentheindustrysstandarddummytexteversincethe1500swhenanunknownprintertookagalleyoftypeandscrambledittomakeatypespecimenbookIthassurvivednotonlyfivecenturiesbutalsotheleapintoelectr

字符串給了錯誤: LoremIpsumissimplydummytextoftheprintingandtypesettingindustryLoremIpsumhasbeentheindustrysstandarddummytexteversincethe1500swhenanunknownprintertookagalleyoftypeandscrambledittomakeatypespecimenbookIthassurvivednotonlyfivecenturiesbutalsotheleapintoelect1

S飾吳給了錯誤: LoremIpsumissimplydummytextoftheprintingandtypesettingindustryLoremIpsumhasbeentheindustrysstandarddummytexteversincethe1500swhenanunknownprintertookagalleyoftypeandscrambledittomakeatypespecimenbookIthassurvivednotonlyfivecenturiesbutalsotheleapintoelect2

字符串給了錯誤: LoremIpsumissimplydummytextoftheprintingandtypesettingindustryLoremIpsumhasbeentheindustrysstandarddummytexteversincethe1500swhenanunknownprintertookagalleyoftypeandscrambledittomakeatypespecimenbookIthassurvivednotonlyfivecenturiesbutalsotheleapintoelect123

不給錯誤: LoremIpsumissimplydummytextoftheprintingandtypesettingindustryLoremIpsumhasbeentheindustr ysstandarddummytexteversincethe1500swhenanunknownprintertookagalleyoftypeandscrambledittomakeatypespecimenbookIthassurvivednotonlyfivecenturiesbutalsotheleapintoelec1

不給錯誤: LoremIpsumissimplydummytextoftheprintingandtypesettingindustryLoremIpsumhasbeentheindustrysstandarddummytexteversincethe1500swhenanunknownprintertookagalleyoftypeandscrambledittomakeatypespecimenbookIthassurvivednotonlyfivecenturiesbutalsotheleapintoelec2

不給錯誤: LoremIpsumissimplydummytextoftheprintingandtypesettingindustryLoremIpsumhasbeentheindustrysstandarddummytexteversincethe1500swhenanunknownprintertookagalleyoftypeandscrambledittomakeatypespecimenbookIthassurvivednotonlyfivecent uriesbutalsotheleapintoelec3

請注意以上樣品的最後幾個字符的差異。第一個存儲的字符串有256個字符。即使列不是主鍵,如果「索引:是(無重複)允許」,該列的表設計中的值設置爲true,但問題仍然存在。

+3

旁邊的問題:爲什麼你要一個*長文本*字段的主鍵?爲什麼不使用自動編號字段?你是否真的要加入這個領域,還是你想限制它獨特的文字? – LittleBobbyTables

+0

@LittleBobbyTables是的,它是獨特的文字。即使它不是主鍵,如果該列的表設計中設置了無重複值允許值,問題依然存在。 –

+3

索引備忘錄字段是一個不穩固的命題。索引鍵僅使用備註字段值中的前255個字符。 – HansUp

回答

5

正如@HansUp在註釋中所述,Access(特別是Jet/ACE數據庫引擎)僅使用Memo/Long Text字段的前255個字符來創建其索引。因此,它只使用前255個字符來執行無重複。

@ HansUp建議使用不同的數據庫引擎,以便爲長字符串和全文搜索提供更好的支持,這可能是最好的方法,但我知道其他考慮可能限制您在Access中解決問題。

因此,這裏是一個Access-only方法來解決你的問題。這假定您在評論中列出的要求是有效的;即,您需要存儲400至1000個字符的唯一字符串。


替代1

  1. 請您最初的備忘錄/長文本字段:備註
  2. 創建四個文本字段(沒有備註/長文本)250個字符最大:Notes1,Notes2,Notes3,備註4
  3. 設置全部四個文本字段:必需 - > True和允許零長度 - > True(確保爲小於751個字符的字符串強制使用唯一索引)
  4. 創建唯一索引並將所有四個文本字段添加到該索引
  5. 不要忽略索引中的空值
  6. 當您存儲這些值時,您需要將它們存儲在Notes字段中,並將字符串拆分爲四個較小的NotesX字段

備選方案2:

保持當前設置和執行在代碼級別唯一性。每次更新或插入筆記時,請在與前255個字符匹配的所有筆記上進行搜索,讀取值並在代碼中執行比較。


方案3(感謝@HansUp在評論提示這一點):

  1. 請您最初的備忘錄/長文本字段:備註
  2. 創建16個或32個字符的文本字段來存儲您的長文本的256位或512位散列:NotesHash
  3. 爲您的NotesHash字段添加唯一索引
  4. 每當備忘錄LD變化時,重新計算散列值,並試圖將其存儲在表

註釋此方法

  • 作爲pigeonhole principle容易證明,存在這樣的可能性,兩種不同的字符串會產生相同的散列(碰撞)。但是,使用好的散列算法會使實際的概率趨近於零。
  • 這個site提供了各種哈希算法的一些VB6/VBA/VBScript實現。我無法保證他們的正確性,但他們通過了眼睛測試。使用風險自負,但這至少是一個很好的起點。
  • 真的,你可以使用任何deterministic function返回一個255個字符或更少的字符串給任意大的輸入。糟糕的哈希算法和好的哈希算法之間的區別在於它如何最大限度地減少衝突。出於這個原因,我建議你使用基於流行標準的。

是的,我仍然強烈建議@ HansUp的解決方案簡單地使用不同的數據庫引擎。

+0

+1我喜歡它。如何計算備忘錄文本的散列,將散列存儲在文本字段中,以及(間接)在散列字段上使用唯一索引強制備忘錄字段的唯一性?至少索引的大小可以合理,並且您可以避免重複存儲備忘錄「塊」。這是一個很長的路要走......但我們同意這不是Access適合的任務。 :-) – HansUp

+1

@HansUp:好主意,不知道爲什麼我沒有想到它。特別是因爲我最近一直在討論散列用於不同的項目。雖然它不適用於我們的項目,但我們實際上正在討論如何使用散列來加速搜索並識別任意大型項目的重複項。 OP正在處理的問題恰恰在這裏! – mwolfe02

+0

我真的很欣賞你描述哈希方法的方式。謝謝。 – HansUp

相關問題