增加數(shù)據(jù)操作日志記錄

需求:API接口--【SaaS后臺(tái)】增加數(shù)據(jù)操作日志記錄

目前做的

實(shí)現(xiàn)過程

1.service中調(diào)用


  1. 異步處理數(shù)據(jù)及存儲(chǔ)

2.1數(shù)據(jù)處理(展示替換)

2.2數(shù)據(jù)處理(數(shù)據(jù)對(duì)比)

/**
     * 對(duì)比節(jié)點(diǎn)數(shù)據(jù)
     *
     * @param oldNode          舊節(jié)點(diǎn)數(shù)據(jù)
     * @param newNode          新節(jié)點(diǎn)數(shù)據(jù)
     * @param operationDetails 操作詳情列表
     */
    private void compareJsonNodes(JsonNode oldNode, JsonNode newNode, List<OperationDetails> operationDetails) {
        // 檢查兩個(gè)節(jié)點(diǎn)是否都是數(shù)組
        if (oldNode.isArray() && newNode.isArray()) {
            int minSize = Math.min(oldNode.size(), newNode.size());
            for (int i = 0; i < minSize; i++) {
                compareJsonNodes(oldNode.get(i), newNode.get(i), operationDetails);
            }
            for (int i = minSize; i < oldNode.size(); i++) {
                compareJsonNodes(oldNode.get(i), createEmptyNode(oldNode.get(i)), operationDetails);
            }
            for (int i = minSize; i < newNode.size(); i++) {
                compareJsonNodes(createEmptyNode(newNode.get(i)), newNode.get(i), operationDetails);
            }
            return;
        }
        List<SysOperationLogTrackEnum> childNodes = getChildNodes();
        Iterator<Map.Entry<String, JsonNode>> newFields = newNode.fields();
        // 處理新數(shù)據(jù)中的字段
        while (newFields.hasNext()) {
            Map.Entry<String, JsonNode> entry = newFields.next();
            String fieldName = entry.getKey();
            Optional<SysOperationLogTrackEnum> operationLogTrackEnum = childNodes.stream()
                    .filter(r -> r.getColumnName().equals(fieldName))
                    .findFirst();
            if (operationLogTrackEnum.isPresent()) {
                SysOperationLogTrackEnum sysOperationLogTrackEnum = operationLogTrackEnum.get();
                JsonNode newValue = entry.getValue();
                JsonNode oldValue = oldNode.get(fieldName);
                if ((newValue == null || newValue.isNull()) && (oldValue != null && !oldValue.isNull())) {
                    OperationDetails operationDetail = sysOperationLogTrackEnum.replaceValues(
                            fieldName, handleJsonNode(oldValue), null
                    );
                    operationDetails.add(operationDetail);
                } else if (oldValue == null || oldValue.isNull() && (newValue != null && !newValue.isNull())) {
                    OperationDetails operationDetail = sysOperationLogTrackEnum.replaceValues(
                            fieldName, null, handleJsonNode(newValue)
                    );
                    operationDetails.add(operationDetail);
                } else if (oldValue.equals(newValue)) {
                } else if (!sysOperationLogTrackEnum.getChildNodes().isEmpty()) {
                    sysOperationLogTrackEnum.compareJsonNodes(oldValue, newValue, operationDetails);
                } else {
                    OperationDetails operationDetail = sysOperationLogTrackEnum.replaceValues(
                            fieldName, handleJsonNode(oldValue), handleJsonNode(newValue)
                    );
                    operationDetails.add(operationDetail);
                }
            }
        }
    }

存在的疑問

1.不可避免的需要數(shù)據(jù)對(duì)比寿桨,這種方式是否可行
2.誰來定義哪些字段需要對(duì)比
3.需要默認(rèn)展示方式如何展示钧唐,使用參數(shù)占位符如何展示

待優(yōu)化

刪除原始數(shù)據(jù)的存儲(chǔ)
異步線程池進(jìn)行存儲(chǔ)
參數(shù)占位符入?yún)⒄故?br> 空間換時(shí)間把子節(jié)點(diǎn)數(shù)據(jù)做成hashMap存儲(chǔ)減少時(shí)間復(fù)雜度
可以添加一個(gè)操作對(duì)象字段
可以把展示的方式改成一句話
展示時(shí)可以進(jìn)行對(duì)比標(biāo)記新增或刪除的內(nèi)容

假設(shè)

在只有兩層遞歸結(jié)構(gòu)的情況下佣渴,如果第一層包含數(shù)組,且每層大約有 10 個(gè)字段君躺,我們可以更具體地計(jì)算時(shí)間復(fù)雜度竿滨。

  • 第一層有一個(gè)數(shù)組魁巩,數(shù)組長(zhǎng)度為 n
  • 每個(gè)數(shù)組元素是一個(gè) JSON 對(duì)象辽旋,包含大約 10 個(gè)字段。
  • 第二層遞歸處理這些 JSON 對(duì)象中的字段檐迟。

分析

1. 第一層數(shù)組處理

  • 數(shù)組長(zhǎng)度為 n补胚。
  • 對(duì)數(shù)組中的每個(gè)元素,調(diào)用 compareJsonNodes 處理其內(nèi)部的 JSON 對(duì)象追迟。由于數(shù)組長(zhǎng)度為 n溶其,這一層的時(shí)間復(fù)雜度為 O(n)

2. 第二層字段處理

  • 假設(shè)每個(gè) JSON 對(duì)象包含 k 個(gè)字段(在你的例子中 k ≈ 10)敦间。
  • 處理每個(gè)字段時(shí)瓶逃,可能需要對(duì) childNodes.stream().filter(...).findFirst() 進(jìn)行線性搜索。假設(shè) childNodes 的大小為 m每瞒,則對(duì)每個(gè)字段的處理時(shí)間為 O(m)金闽。
  • 第二層遞歸的復(fù)雜度為 O(k * m)。由于 k ≈ 10剿骨,可以視為常數(shù)代芜,復(fù)雜度為 O(m)

綜合計(jì)算

  • 第一層的時(shí)間復(fù)雜度是 O(n)浓利。
  • 每個(gè)數(shù)組元素在第二層的時(shí)間復(fù)雜度為 O(m)挤庇,由于有 n 個(gè)元素,總體時(shí)間復(fù)雜度為 O(n * m)贷掖。

總時(shí)間復(fù)雜度

在這種情況下嫡秕,代碼的總時(shí)間復(fù)雜度為 O(n * m),其中:

  • n 是第一層數(shù)組的長(zhǎng)度苹威。
  • mchildNodes 的大小昆咽。

由于 k ≈ 10,這個(gè)部分基本可以視為常數(shù),不影響整體的時(shí)間復(fù)雜度計(jì)算掷酗。


a. 測(cè)試不同 n 值的性能表現(xiàn)调违,驗(yàn)證 O(n * m) 的實(shí)際影響。
b. 考慮優(yōu)化 childNodes 搜索部分泻轰,減少 m 的影響技肩。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市浮声,隨后出現(xiàn)的幾起案子虚婿,更是在濱河造成了極大的恐慌,老刑警劉巖泳挥,帶你破解...
    沈念sama閱讀 221,430評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件然痊,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡羡洁,警方通過查閱死者的電腦和手機(jī)玷过,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,406評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來筑煮,“玉大人辛蚊,你說我怎么就攤上這事≌嬷伲” “怎么了袋马?”我有些...
    開封第一講書人閱讀 167,834評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)秸应。 經(jīng)常有香客問我虑凛,道長(zhǎng),這世上最難降的妖魔是什么软啼? 我笑而不...
    開封第一講書人閱讀 59,543評(píng)論 1 296
  • 正文 為了忘掉前任桑谍,我火速辦了婚禮,結(jié)果婚禮上祸挪,老公的妹妹穿的比我還像新娘锣披。我一直安慰自己,他們只是感情好贿条,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,547評(píng)論 6 397
  • 文/花漫 我一把揭開白布雹仿。 她就那樣靜靜地躺著,像睡著了一般整以。 火紅的嫁衣襯著肌膚如雪胧辽。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,196評(píng)論 1 308
  • 那天公黑,我揣著相機(jī)與錄音邑商,去河邊找鬼摄咆。 笑死,一個(gè)胖子當(dāng)著我的面吹牛人断,可吹牛的內(nèi)容都是我干的豆同。 我是一名探鬼主播,決...
    沈念sama閱讀 40,776評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼含鳞,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了芹务?” 一聲冷哼從身側(cè)響起蝉绷,我...
    開封第一講書人閱讀 39,671評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎枣抱,沒想到半個(gè)月后熔吗,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,221評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡佳晶,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,303評(píng)論 3 340
  • 正文 我和宋清朗相戀三年桅狠,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片轿秧。...
    茶點(diǎn)故事閱讀 40,444評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡中跌,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出菇篡,到底是詐尸還是另有隱情漩符,我是刑警寧澤,帶...
    沈念sama閱讀 36,134評(píng)論 5 350
  • 正文 年R本政府宣布驱还,位于F島的核電站嗜暴,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏议蟆。R本人自食惡果不足惜闷沥,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,810評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望咐容。 院中可真熱鬧舆逃,春花似錦、人聲如沸疟丙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,285評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽享郊。三九已至览祖,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間炊琉,已是汗流浹背展蒂。 一陣腳步聲響...
    開封第一講書人閱讀 33,399評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工又活, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人锰悼。 一個(gè)月前我還...
    沈念sama閱讀 48,837評(píng)論 3 376
  • 正文 我出身青樓柳骄,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親箕般。 傳聞我的和親對(duì)象是個(gè)殘疾皇子耐薯,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,455評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容