我有一個包含數百萬電子郵件ID記錄的註冊表。電子郵件ID是獨一無二的。爲了進行身份驗證,使用asp.net將它們編入索引並獲取它們的最佳方法是什麼?我的意思是我應該將電子郵件ID列定義爲聚集的唯一索引而不是UNIQUE?在MYSQL中索引電子郵件地址的最佳方法是什麼
回答
當你有一個可變長度的文本輸入,如e-mail或地址,但你希望他們是唯一的,則標準方法是指數的哈希那個價值。
原因:散列是固定長度的,並且您避免了超出索引長度的文本數據的問題。
根據您的意見,你有看起來像這樣的表(我故意省略密碼和手機號碼):
create table users (
user_id int not null unsigned auto_increment,
first_name varchar(255) not null,
surname varchar(255) default null,
email varchar(255) not null,
primary key(id)
) engine = innodb;
我會改變該表,並添加包含電子郵件散列的字段。我會通過觸發器保持這一點,以便您可以專注於獲取有效數據,而不用擔心創建哈希。爲此,該字段將爲binary(20)
,因爲它將包含原始散列並佔用20個字節。既然我們想通過觸發來維護它,那麼我們需要使該字段可爲空且唯一。注意:你可以把它binary(40)
表:
create table users (
user_id int not null unsigned auto_increment,
email_hash binary(20) default null, -- this is the field in question
first_name varchar(255) not null,
surname varchar(255) default null,
email varchar(255) not null,
primary key(id),
unique(email_hash) -- this is the unique index over the hash
) engine = innodb;
,我們現在需要的是一個觸發器,它與電子郵件哈希交易。我將介紹如何在插入前創建維護此信息的觸發器。類似的邏輯適用於更新表格:
DELIMITER $$
CREATE TRIGGER users_before_insert BEFORE INSERT ON `users`
FOR EACH ROW BEGIN
SET NEW.email_hash = UNHEX(SHA1(new.email)); -- You can remove UNHEX if you want human-readable value. You'll need binary(40) to hold it then
END;
DELIMITER ;
從您的應用程序中,您只需提供名字,姓氏和電子郵件的值。 MySQL會處理重複項,它會告訴你狀態爲23000
。我不知道如何使用asp.net
,所以你必須以某種方式適應錯誤處理。
你可以在你的asp.net應用程序中處理哈希,但如果你感覺數據庫這樣做更舒服 - 我展示瞭如何通過觸發器實現它。
如果您需要手機號碼是唯一的或任何其他字段,則同樣的規則適用於手機號碼。當然,哈希數可能會產生比實際數更長的哈希值,在這種情況下,您可能直接將手機號碼設爲unique
。
我希望這可以幫助你決定做什麼。
如果你正在做一個獨特的密鑰查找,它確實沒有足夠的性能差異來擔心索引是否被聚集。在向表中添加更多內容時,對其進行羣集可能是有意義的(或不是)。主要的是你有一個唯一的約束,很可能這將是主鍵,所以你會得到這個和相應的索引。性能會很好 - 關注其他用途。例如如果您想對域進行分析,則可能需要分解電子郵件地址。這可能更重要。最喜歡的事情,這取決於....
感謝您的幫助。但我想澄清一件事。我有一個單獨的ID列,我已經聲明爲主鍵,但是我正在考慮將emailID聲明爲主鍵和Auto inc。因爲我已經宣佈它是唯一的。如果我有數百萬條記錄,它肯定會減少我的數據庫的大小。如果我錯了,請糾正我。謝謝.. :) – Deep
@Deep - 什麼是'emailID'?電子郵件地址的價值?你打算如何使自動遞增?只需保留主鍵,將電子郵件的散列添加爲「唯一」,這樣您就不會重複,並且所有問題都消失了。您可以快速查詢,您可以快速檢索,您可以只插入唯一的電子郵件 - 不要過度使用它,因爲您會發現哪裏沒有問題。數以百萬計的記錄都不算什麼,所以不要過於擔心數百萬條記錄。 – Mjh
您不需要此ID。即使你決定包含它,你也需要在電子郵件中添加一個唯一的非空限制,這實際上是PK。如果你需要在電子郵件上使用外鍵,那麼可能會保留該ID,但這不在你在這裏描述的範圍內。不知道爲什麼Mjh對電子郵件進行哈希處理如此堅持 - 這不是必要的,會使所有事情複雜化,併爲錯誤開放。我不會那樣做。 – LoztInSpace
事情太多了評論...
如果你已經有INDEX(email)
,然後簡單地把它變成UNIQUE(email)
。表格(數據+索引)的大小不會改變(比ALTER
多一點)。
如果email
太大而無法索引 - 比如因爲它是TEXT
- 那麼無法在email
上添加UNIQUE
索引。在這種情況下,「散列」解決方案將起作用。是的,它會爲磁盤使用增加兆字節,但這不太可能成爲問題。
如果您目前有id AUTO_INCREMENT
和PRIMARY KEY(id)
,那麼您是否真的在其他表中使用id
?如果沒有,那麼我們可以討論其他路徑,例如使email
或hash
PRIMARY KEY
。這可能甚至縮小磁盤的足跡。
不管你做什麼,都使用InnoDB。
如果不存儲電子郵件ID的散列,而只是將emai_id聲明爲主鍵而不爲空,它會爲我做這件事嗎?但主鍵本身是一個獨特的聚集索引,這對我來說可能是一個問題。 – Deep
使用'PRIMARY KEY(email)','INSERT''再次發送同一封電子郵件將失敗(重複密鑰)。另見'INSERT ... ON DUPLICATE KEY UPDATE ...'。 –
- 1. 在MySQL中索引電子郵件地址的最有效方法是什麼?
- 2. 在WinForms中驗證電子郵件地址的最佳方法
- 3. 在Swift中驗證電子郵件地址的最佳做法是什麼?
- 4. 查詢ContactsContract以同時獲取電子郵件,電話和地址的最佳方法是什麼?
- 5. 最長的電子郵件地址是什麼?
- 6. 電子郵件地址驗證的最佳做法(包括Gmail中的+地址)
- 7. 實現電子郵件發送的最佳方式是什麼?
- 8. 創建默認電子郵件的最佳方式是什麼?
- 9. 什麼是解析短信電子郵件的最佳方式?
- 10. 什麼是驗證電子郵件域的最佳方式?
- 11. 從索引索引中刪除電子郵件地址
- 12. 在codeigniter中獲得具有相同電子郵件地址域的用戶的最佳方式是什麼?
- 13. 從電子郵件中提取相關信息的最佳方法是什麼?
- 14. 電子郵件中HTML最可靠的clearfix方法是什麼?
- 15. 通過Zend通過電子郵件搜索的最佳方式是什麼?
- 16. 轉發Outlook電子郵件附件的最佳VB方法是什麼?
- 17. MySQL索引 - 什麼是最佳實踐?
- 18. 獲取用戶的主要電子郵件地址mysql php最佳做法
- 19. 開源代碼中電子郵件地址的最佳實踐?
- 20. 什麼是最好從/電子郵件驗證方法在PHP?
- 21. 什麼是更新流星中的用戶電子郵件地址的最佳方式?
- 22. 檢查電子郵件是否存在的最佳方法
- 23. 在ASP.NET中發送大批量電子郵件的最佳方式是什麼?
- 24. 在PHP中發送安全電子郵件的最佳方式是什麼
- 25. 什麼是使用System.Net.Mail格式化電子郵件的最佳方法
- 26. 什麼是檢查電子郵件cc字段中的不正確的電子郵件地址在java中的最佳方式
- 27. 電子郵件通知最簡單的方法是什麼3
- 28. 模板電子郵件的最佳電子郵件方式
- 29. 在電子郵件地址
- 30. 什麼是可靠地處理電子郵件附件的最佳庫?
您使用的是MySQL還是MSSQL? MySQL沒有聚集的唯一索引。你可以對電子郵件進行散列處理(比如用'sha1'),並將其保存爲二進制文件,每次將腳印減少到20個字節,並且該列旁邊有明文電子郵件地址值。使哈希獨一無二,現在您擁有固定長度的唯一標識符。 – Mjh
對電子郵件地址進行散列處理,將它們轉換爲二進制文件,然後將它們存儲在電子郵件列旁邊的數據庫中是什麼意思。它會增加數據庫的大小。它不會解決我的問題,反而會增加它。我想通過實施索引來縮短查詢時間。 – Deep
電子郵件地址具有可變長度。如果您散列可變長度值,您的索引將會有所不同,並且當您嘗試索引過大的值時,索引還有其他問題。爲了減少這個問題,你不需要索引電子郵件的實際字符串值,但是它的哈希值是因爲哈希值是固定長度的。它確實解決了你的問題,並且你沒有任何可以來回轉換的東西。 – Mjh