判斷從表的外鍵是否包含所有主表的主鍵

我們知道數(shù)據(jù)庫(kù)中有以下幾個(gè)概念:

  • 主鍵:一般情況下,滿足第一范式的表都有一個(gè)主鍵Primary key,用于唯一標(biāo)示數(shù)據(jù)庫(kù)中的一個(gè)字段
  • 外鍵: 外鍵是相對(duì)于數(shù)據(jù)庫(kù)設(shè)計(jì)中的參考完整性而言,它與主鍵之間是彼此依賴的關(guān)系。
  • 主表: 在數(shù)據(jù)庫(kù)中建立的表格即Table,其中存在主鍵(primary key)用于與其它表相關(guān)聯(lián),并且作為在主表中的唯一性標(biāo)識(shí)
  • 從表: 以主表的主鍵(primary key)值為外鍵 (Foreign Key)的表,可以通過(guò)外鍵與主表進(jìn)行關(guān)聯(lián)查詢。從表與主表通過(guò)外鍵進(jìn)行關(guān)聯(lián)查詢

有如下兩個(gè)表,主表是fansArr,是粉絲的信息記錄。主鍵:fans_id,格式為 xxx-xxx-xx 表示一個(gè)32位的字符,避免重復(fù)。

const fansArr = [
    {
        fans_id: 'xxx-xxx-xx1',
        name: 'xx'
    },
    {
        fans_id: 'xxx-xxx-xx2',
        name: 'xy'
    }
];

從表是imgArr, 是所有粉絲圖片的記錄。外鍵是 fansId,

const imgArr = [
    {
        fansId: 'xxx-xxx-xx1',
        imgUrl: 'xxxx.jpg'
    },
    {
        fansId: 'xxx-xxx-xx1',
        imgUrl: 'xxxx.jpg'
    },
    {
        fansId: 'xxx-xxx-xx2',
        imgUrl: 'xxxx.jpg'
    },
    {
        fansId: 'xxx-xxx-xx1',
        imgUrl: 'xxxx.jpg'
    }
];

不難發(fā)現(xiàn),粉絲和粉絲個(gè)人圖片是 一對(duì)多 的關(guān)系。

問(wèn)題

現(xiàn)在有個(gè)需求,每個(gè)粉絲至少一張圖片,怎么校驗(yàn)?

解法一: 外鍵去重
弊端:性能低,因?yàn)橐粚?duì)多的關(guān)系,當(dāng)外表記錄的信息太多時(shí),遍歷次數(shù)太多。

 /**
  * 遍歷 imgArr 數(shù)組,得到所有 fansId 
  */
function emptyFn1() {
    let arr = [];
    imgArr.forEach( img => {
        if(!arr.includes(img.fansId)) {
            arr.push(img.fansId)
        }
    })
    return arr.length !== fansArr.length
}

哈哈哈,方法一并不總是有效的?。?!仔細(xì)看看問(wèn)題出在哪里?
理想情況下外表是根據(jù)主表的主鍵作為外鍵來(lái)記錄信息的,但是如果主表的主鍵改了,而外表的外鍵沒(méi)有更改,方法一只是保證了主鍵和外鍵的數(shù)量一致,但內(nèi)容不一定一樣。不信把 fansArr[0].fans_id 改成 xxx-xxx-xx3 試試

解法二: 遍歷主表,獲取所有在從表中出現(xiàn)的fans_id

 function emptyFn2() {
    let arr = [];
    let str = JSON.stringify(imgArr);
    fansArr.forEach(fans => {
        if(str.includes(fans.fans_id)) {
            arr.push(fans.fans_id)
        }
    })
    return arr.length !== fansArr.length
}

對(duì)解法二的優(yōu)化:forEach 會(huì)遍歷所有,實(shí)際可能并不需要遍歷全部

function emptyFn3() {
    let str = JSON.stringify(imgArr);
       if(fansArr.length > 0) {
        return !fansArr.every(fans => {
            return str.includes(fans.fans_id)
        })
    }
    throw new Error('主表是空的');
}

方法 二、三的弊端
fans_id 如果不是唯一的字符串,則存在不確定性
例如 fans_id 是普通的 1, 2, 3, 則字符串中可能存在干擾項(xiàng)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容