2016-02-20 36 views
1

我對NoSQL和反規範化非常陌生。不過,我想允許在SignUp行動中我的應用程序定義爲:如何正確標準化Firebase中的數據

  1. 如果用戶名已被使用,則不允許用戶使用它
  2. 如果電話號碼已被使用,那麼用戶不得使用
  3. 允許新用戶「同步」他們的電話號碼與服務器聯繫,以確定誰是當前用戶,並檢索其各自的UID

我已經架構概括爲下面給出了快速需要檢查用戶名/電話號碼MBER已經存在於用戶註冊,以及所需要的搜索和比較給定,如果新用戶的聯繫人的電話號碼是鏈接到用戶在應用程序中已經存在:

{ 
    "presentUsersByPhoneNumber" : { 
    "1614#######" : { 
     "uid" : "fdb17f3a-7b7d-4aa5-9a0b-b9fb33c349de" 
    }, 
    "1614#######" : { 
     "uid" : "99e4989b-a046-4c5f-9478-5ebd8bdc3ded" 
    }, 
    "1614#######" : { 
     "uid" : "1783917f-00e4-47a0-b2cd-987bdf185129" 
    }, 
    "1614#######" : { 
     "uid" : "a96da7b1-7c4e-44bc-b82e-fc75bed52bcd" 
    } 
    }, 
    "presentUsersByUsername" : { 
    "ak" : { 
     "uid" : "a96da7b1-7c4e-44bc-b82e-fc75bed52bcd" 
    }, 
    "ak2" : { 
     "uid" : "99e4989b-a046-4c5f-9478-5ebd8bdc3ded" 
    }, 
    "ak3" : { 
     "uid" : "1783917f-00e4-47a0-b2cd-987bdf185129" 
    }, 
    "kja" : { 
     "uid" : "fdb17f3a-7b7d-4aa5-9a0b-b9fb33c349de" 
    } 
    }, 
    "users" : { 
    "1783917f-00e4-47a0-b2cd-987bdf185129" : { 
     "phoneNumber" : "614#######", 
     "username" : "ak3" 
    }, 
    "99e4989b-a046-4c5f-9478-5ebd8bdc3ded" : { 
     "phoneNumber" : "1614#######", 
     "username" : "ak2" 
    }, 
    "a96da7b1-7c4e-44bc-b82e-fc75bed52bcd" : { 
     "phoneNumber" : "1614#######", 
     "username" : "ak1" 
    }, 
    "fdb17f3a-7b7d-4aa5-9a0b-b9fb33c349de" : { 
     "phoneNumber" : "1614#######", 
     "username" : "kja" 
    } 
    } 
} 

是這種方法要在太公平去規範化的行爲?

回答

1

在NoSQL中,您應該針對應用程序需要訪問的數據建模數據。請閱讀了解更多信息。

因此,如果您需要一種有效的方式來檢查電話號碼或用戶名是否已被佔用,那麼爲這些存儲映射是有意義的。我可能會做不同的唯一的事情有將它們存儲爲簡單類型:

"phoneNumberToUid" : { 
    "1614#######" : "fdb17f3a-7b7d-4aa5-9a0b-b9fb33c349de" 
    "1614#######" : "99e4989b-a046-4c5f-9478-5ebd8bdc3ded" 
}, 
"usernameToUid" : { 
    "ak" : "a96da7b1-7c4e-44bc-b82e-fc75bed52bcd" 
    "ak2" : "99e4989b-a046-4c5f-9478-5ebd8bdc3ded" 
} 

一件事,我在你的樣品數據注意到的是,你有presentUsersByUsername關鍵ak,但沒有相應的兒童users與那name。這通常發生是因爲您的代碼要麼中止,要麼因爲您在開發過程中的某個時候犯了錯誤。

您可以防止許多這類問題是:採用多位置更新

  1. ,以便所有寫操作都作爲單個命令

    ref.update({ 
        '/users/a96da7b1-7c4e-44bc-b82e-fc75bed52bcd/username': 'ak1', 
        '/usernameToUid/ak': null, 
        '/usernameToUid/ak1': 'a96da7b1-7c4e-44bc-b82e-fc75bed52bcd' 
    }); 
    

    發送到火力地堡此更新是最安全的方法將用戶的名稱從ak更改爲ak1,擦除舊映射並添加一個新映射。

  2. 使用驗證規則確保每個名稱的用戶存在

    "usernameToUid": { 
        "$username": { 
        ".validate": "newData.parent().parent().child(newData.va()).child('username').val() == $username" 
        } 
    }