登录 立即注册

找到374个回复 (用户: 无名啊)

无名啊 7楼回复 淡然问一个 VueJs 的问题 (2022-10-29//)

@淡然,回调 PromptSetValue(v => item.it = v) 或 异步 PromptSetValue().then(v => item.it = v)

无名啊 5楼回复 淡然问一个 VueJs 的问题 (2022-10-29//)

@淡然function PromptSetValue(e, key)

无名啊 3楼回复 淡然问一个 VueJs 的问题 (2022-10-29//)

@淡然,下面的写法有何不妥吗?你原始问题是啥?

无名啊 1楼回复 淡然问一个 VueJs 的问题 (2022-10-29//)

@淡然,因为 js 没法引用对象的键?

无名啊 11楼回复 无名啊用于解决树形结构存储的闭包表,凭什么能快速获取某个节点的祖先节点/父节点/子节点? (2022-10-26//)

@老虎会游泳,老虎这么多年,没有啥树形数据要存吗?之前都用的啥方案?

无名啊 12楼回复 庸人大佬萌们,如何从JQ中取出数组赋值给变量 (2022-10-26//)

@庸人

主要是我其实更习惯用管道这样的方式

不能在匿名管道内修改外部的变量!(如:jq | readarraysum=0; seq 3 | while read -r i; do (( sum += i )); done

理由

因为这会开启一个子 shell,然后在子 shell 中,readarrayjq 的输出转成数组。

等这一行执行完毕,子 shell 就会退出,刚整理好的数组也随着进程结束而消失了。

那用啥?

所以,只能用 <<<< <(...) 的形式。

  • 前者需要完全准备好一个字符串,再作为 stdin 喂给所在的命令。我觉得没必要,没这么干

    (试想,你拷贝一个 1GB 的文件,会申请 1GB 的内存,全部读取完成后,再写入至新文件吗?)

  • 后者,<(...) 是将 ...stdout 重定向至某个文件(一般是具名管道),然后将此文件作为 stdin 喂给所在命令

    (如果是管道实现,则一般是 4KB 缓冲区)

但是当我单拧出来一个数组,那么结尾就会有一个换行🤣🤣

使用 readarray 时指定 -t 参数,会自动删除行末的换行符

无名啊 9楼回复 无名啊用于解决树形结构存储的闭包表,凭什么能快速获取某个节点的祖先节点/父节点/子节点? (2022-10-26//)

@老虎会游泳,那个博主给出新的解决方案了,速度上确实应该会很快,但空间占用也很恐怖。。

更改表结构和建立索引

那个博主新的表结构为:

CREATE TABLE 闭包表 (
    祖先 INT,
    后代 INT,
    距离 INT,
    PRIMARY KEY (后代, 距离),
    KEY (祖先, 距离)
);

使得有如下两种索引:

  • 聚集索引:(后代, 距离, 祖先)
  • 二级索引:(祖先, 距离, 后代)

就能高效应对下列查询了:

  • (孙)子/后代节点:走二级索引 (✔查询节点, ✔1 或 2 或 任意, ❓<要获取的后代节点>)
  • (祖)父/祖先节点:走聚集索引 (✔查询节点, ✔1 或 2 或 任意, ❓<要获取的祖先节点>)

下列查询会小范围扫表,但问题不大:

  • 某后代节点与某祖先节点的距离:走聚集索引 (✔查询后代节点, ❓<要获取的距离>, ❌查询祖先节点)

    只要 查询后代节点 层级没有深到离谱,扫表范围也就连续的几行几十行而已。

占的空间太大了,怀疑性价比

一个 66W 的 5 级地区表,就要配套一个相当于 780W 的闭包表,快接近 12 倍于主表的辅助表了。。

如此恐怖的空间换时间方案,到底能快多少呢?真的值得投入这么多空间来提速吗?

无名啊 8楼回复 庸人大佬萌们,如何从JQ中取出数组赋值给变量 (2022-10-25//)

@庸人,你的需求是要备份当下的网易云歌单吗?还是啥。。

无名啊 6楼回复 庸人大佬萌们,如何从JQ中取出数组赋值给变量 (2022-10-25//)

@庸人,你说下原始需求,感觉会有更好的实现方式

无名啊 4楼回复 庸人大佬萌们,如何从JQ中取出数组赋值给变量 (2022-10-25//)

@庸人,比如:

$ readarray -td $'\0' arr < <(jq -rj '[.[].name] | join("\u0000")' <<<'[{"id": 1, "name": "a\nb\n"}, {"id": 2, "name": "c\nd"}]')
$ declare -p arr
declare -a arr=([0]=$'a\nb\n' [1]=$'c\nd')

如果你不担心你的 name 里有换行符的话,可以直接:

$ readarray -t arr < <(jq -r '.[].name' <<<'[{"id": 1, "name": "ab"}, {"id": 2, "name": "cd"}]')
$ declare -p arr
declare -a arr=([0]='ab' [1]='cd')
无名啊 3楼回复 庸人大佬萌们,如何从JQ中取出数组赋值给变量 (2022-10-25//)

@庸人,直接回答:可以用 Bashreadarray 来一次性读到某个数组

另外:

  1. Bash Shell 更适合交互式和简单脚本使用。含有数组、字典甚至更复杂数据结构的,可能都值得你考虑换其他语言了
  2. 不想换的话,考虑尽量用 jq 来一次性生成你最终要的数据?
无名啊 4楼回复 童真再见c盘里有个乱码文件夹,是病毒还是哪个软件的? (2022-10-25//)

@童真再见@tasy5kg,你们都是咋找到这种文件(夹)的?我打开 Everything 都不知道搜点什么关键词。。

无名啊 1楼回复 庸人大佬萌们,如何从JQ中取出数组赋值给变量 (2022-10-25//)

@庸人,你传一下原始 json 文件,和写一下你期望得到的结果呗?

无名啊 1楼回复 虎老会泳游第一次遇到这情况 (2022-10-25//)

@虎老会泳游,不懂

为嘛不直接报价呢?还是说,只是搜集域名对应的联系人?

无名啊 13楼回复 HongKongDolllinux上图片太大,有没有啥命令可以压缩 (2022-10-25//)

@TabKey9,噢,突然明白你的意思了

看来我还是太纯洁了

无名啊 8楼回复 无名啊用于解决树形结构存储的闭包表,凭什么能快速获取某个节点的祖先节点/父节点/子节点? (2022-10-25//)

@老虎会游泳,我是读到一篇博文《在数据库中存储一棵树,实现无限级分类》时知道闭包表的。

(这篇博文还流传很广泛,我在必应上搜 “ClosureTable”,大半文章也参考/引用这篇博文内容/图片)

但看了文章下来后,没看懂为啥高效。。问了博主后,博主将结构改成了:

CREATE TABLE 闭包表 (
+   后代节点ID INT,
    祖先节点ID INT,
-   后代节点ID INT,
    这俩节点距离 INT,
-   PRIMARY KEY (祖先节点ID, 后代节点ID),
+   PRIMARY KEY (后代节点ID, 祖先节点ID)
);

我拿他文中的数据和修改前后的表结构去测试。结论是:

无论是原来的闭包表结构,还是修改后的,在查询祖先/父/子/后代节点时,都有不同程度的大范围扫表现象

下面的 SQL,能自动根据该博主的数据表,建立俩修改前后的闭包表,并进行各种测试,以观察扫了多少行闭包表

-- -------- 原来的闭包表结构 --------

CREATE TABLE IF NOT EXISTS 原来的闭包表 (
  祖先 VARCHAR(16),
  后代 VARCHAR(16),
  距离 INT,
  PRIMARY KEY (祖先, 后代, 距离))
SELECT REPLACE(b.`name`, 'root', '根') 祖先,
       REPLACE(c.`name`, 'root', '根') 后代,
       a.distance 距离
  FROM category_tree a
  JOIN category b ON b.id = a.ancestor
  JOIN category c ON c.id = a.descendant;

-- -------- 修改后的闭包表结构 --------

CREATE TABLE IF NOT EXISTS 修改后闭包表 (
  后代 VARCHAR(16),
  祖先 VARCHAR(16),
  距离 INT,
  PRIMARY KEY (后代, 祖先, 距离))
SELECT REPLACE(b.`name`, 'root', '根') 后代,
       REPLACE(c.`name`, 'root', '根') 祖先,
       a.distance 距离
  FROM category_tree a
  JOIN category b ON b.id = a.descendant
  JOIN category c ON c.id = a.ancestor;

-- 1. 查找子节点
EXPLAIN SELECT 后代 FROM 原来的闭包表 WHERE 祖先 = '根' AND 距离 = 1; -- rows: 14 = COUNT(category)
EXPLAIN SELECT 后代 FROM 修改后闭包表 WHERE 祖先 = '根' AND 距离 = 1; -- rows: 54 = COUNT(category_tree)

-- 2. 查找父节点
EXPLAIN SELECT 祖先 FROM 原来的闭包表 WHERE 后代 = '电脑配件' AND 距离 = 1; -- rows: 54
EXPLAIN SELECT 祖先 FROM 修改后闭包表 WHERE 后代 = 'RTX3080' AND 距离 = 1; -- rows: 6 = 所在层数
-- 上面这行复杂度是 O(N)。若是 1000 层的节点获取父节点,需要扫 1000 行表。

-- 3. 查找祖先节点
EXPLAIN SELECT 祖先 FROM 原来的闭包表 WHERE 后代 = '电脑配件' ORDER BY 距离 DESC; -- rows: 54
EXPLAIN SELECT 祖先 FROM 修改后闭包表 WHERE 后代 = 'RTX3080' ORDER BY 距离 DESC; -- rows: 6

-- 4. 查找后代节点(下面查的,实际是最后一层,没后代的)
EXPLAIN SELECT 后代 FROM 原来的闭包表 WHERE 祖先 = 'RTX3080'; -- rows: 1
EXPLAIN SELECT 后代 FROM 修改后闭包表 WHERE 祖先 = 'RTX3080'; -- rows: 54
无名啊 7楼回复 无名啊用于解决树形结构存储的闭包表,凭什么能快速获取某个节点的祖先节点/父节点/子节点? (2022-10-25//)

@老虎会游泳,这闭包表本身,和你的 KEY (这俩节点距离, 祖先节点)KEY (这俩节点距离, 后代节点) 也差不多大啊,扫索引所有行也快不到哪儿去吧。。

而且,对于问题三(获取某节点所有祖先),这 1170W 的表还是要扫 390W 行:

SELECT 祖先节点 FROM 闭包表 WHERE /* 缺失:祖先节点 = ? AND */ 后代节点 = '...' ORDER BY 距离 DESC
无名啊 5楼回复 无名啊用于解决树形结构存储的闭包表,凭什么能快速获取某个节点的祖先节点/父节点/子节点? (2022-10-25//)

@老虎会游泳,噢,我想起你之前提到过的:

老虎会游泳:如果索引只有两个键,就是遍历两个键,对其值的数量进行求和。

无名啊:你是说,一百行的表,对其中一个值域大小为2的字段建索引,该索引只有两条记录?每条记录指向50个主键ID?(假设均匀分布)

老虎会游泳:对呀,难道不是吗,B+树的一个节点不是能存很多指针吗?除非一个节点存不下,才会需要存储在相邻节点吧。

我后面找到的答案是:不是

下面这张图出自这个博客。可以看到:

  1. 表格前 7 行是 Record Header,无论是聚集/非聚集的叶子/非叶子页上的每个记录,都会有这个 5+ 字节的记录头,先不管。
  2. 表格后 2 行,表明二级索引的叶子页上,只会存着 索引键 和 主键,没有你说的【合并相同的索引键为一行记录】的结构

无名啊 11楼回复 HongKongDolllinux上图片太大,有没有啥命令可以压缩 (2022-10-25//)

@TabKey9,离线版的啥?tinyjpg 吗?为啥不试试 Quality = 70MozJPEG 呢?

无名啊 4楼回复 无名啊用于解决树形结构存储的闭包表,凭什么能快速获取某个节点的祖先节点/父节点/子节点? (2022-10-25//)

@老虎会游泳,加过 explain 了,就是我说的这些情况

这个索引,基本就变成 1170W 的表了。。

下一页 上一页 (13 / 19页)

7月2日 02:09 星期二

本站由hu60wap6华为CPU驱动

备案号: 京ICP备18041936号-1