V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  wxf666  ›  全部回复第 33 页 / 共 33 页
回复总数  656
1 ... 24  25  26  27  28  29  30  31  32  33  
主要是你启动的进程太多,又叠加循环大量关键字了($() 会开启 sub shell ,你还有一堆 echo 、cut )

对于 7s 部分的代码,每测试一个含 : 的参数,你就要开启 3 + 614 * 9 = 5529 次子进程。。。


●针对 7s 部分,以一个参数 'asd:f' 逐步进行测试:

1. 使用 <<<xxx 优化掉 echo xxx ,用时为原来的 74%(即 5.2 秒)

GROUP_NAME1=$(cut -d':' -f 1 <<<"$GROUP_NAME")
GROUP_NAME2=$(cut -d':' -f 2 <<<"$GROUP_NAME")
if [ -n "$(cut -d':' -f 3 <<<"$GROUP_NAME")" ]; then

2. 使用 bash 内置的替换功能,来代替 cut ,用时为原来的 30%(即 2.1 秒)

GROUP_NAME1=$(echo "${GROUP_NAME%%:*}") # 删掉 :.*$
GROUP_NAME2=$(echo "${GROUP_NAME##*:}") # 删掉 ^.*:
if ([[ $GROUP_NAME =~ ^.*:.*: ]]); then  # () 用来开启一次 sub shell

3. 取消掉 $(),用时为原来的 1%(即 0.07 秒)

GROUP_NAME1=${GROUP_NAME%%:*} # 删掉 :.*$
GROUP_NAME2=${GROUP_NAME##*:} # 删掉 ^.*:
if [[ $GROUP_NAME =~ ^.*:.*: ]]; then
  _error "非法字符: ${GROUP_NAME#*:*:}"; exit 1


●另外,bash 也内置了大小写转换功能:

declare -a EXTRAARG=("${@,,}") # 将每个参数的每个字符转为小写
# GROUP_NAME=$(echo "${GROUP_NAME}"|tr "[:upper:]" "[:lower:]") # 去掉这行


●还可考虑使用关联数组,用时为原来的 0.00071%(原 7 秒 可执行 140000 次)

declare -A dict="($(printf "['%s']= " "${MySQLKeywords[@]}"))" # 要求关键字里没有 ' 字符,否则老老实实 for

for GROUP_NAME in "${EXTRAARG[@]}";do

  # 每个参数循环多次测试
   for ((i = 0; i < 140000; i++)); do
    # 删掉 :
     GROUP_NO_SEP=${GROUP_NAME//:}

    # 计算 : 个数(原字符串长度 - 删掉 : 后长度)
     case $(( ${#GROUP_NAME} - ${#GROUP_NO_SEP} )) in
       0)
        [[ -v dict[$GROUP_NAME] ]] || continue
        ;;
       1)
        [[ -v dict[${GROUP_NAME%%:*}] ||
          -v dict[${GROUP_NAME##*:}] ]] || continue
        ;;
      *)
        _error "非法字符: ':${GROUP_NAME#*:*:}'"
         exit 1
        ;;
     esac

    # 出现了关键字
    _error "参数不能为 MySQL 的关键字或保留字!退出中"
     exit 1
   done
done


●或者使用 awk 里的数组,用时为原来的 0.0004%(原 7 秒 可执行 250000 次)

for GROUP_NAME in "${EXTRAARG[@]}";do

  # 每个参数循环多次测试
   for ((i = 0; i < 250000; i++)); do
     echo "$GROUP_NAME"
   done

done | awk -F: '
   BEGIN {
    # 要求关键字里不出现 : " 等字符
     split("'"$(IFS=:; echo "${MySQLKeywords[*]}")"'", arr)
     for (i in arr) dict[arr[i]] = 1;
  }

  {
     if (NF > 2) {
       print "非法字符: " $3
       exit 1
    }

     for (i = 1; i <= NF; i++) {
       if ($i in dict) {
         print "参数不能为 MySQL 的关键字或保留字!退出中"
         exit 1
      }
    }
  }
'
2022-07-12 20:26:38 +08:00
回复了 Sherman07 创建的主题 问与答 磁盘空间不足的情况下, 10 亿级数据库该如何去重?
上面写错了,一行索引存为 (uid: 4 Bytes, 主键 id: 4 Bytes)
2022-07-12 20:17:43 +08:00
回复了 Sherman07 创建的主题 问与答 磁盘空间不足的情况下, 10 亿级数据库该如何去重?
@sadfQED2 会不会他 uid 没加索引。。

即使一行索引只是存为 (uid: 4 Bytes, 页号: 4 Bytes),给 uid 加索引,至少也需要 (10 ^ 9) * 8 Bytes ≈ 7.5 GB 磁盘?

感觉 1 楼说的 bitmap 去重可行啊

如果 UID 为 4 字节,bitmap 需要 (2 ^ 32) bits / 8 (bits/Byte) = 512 MB 内存 /磁盘,

如果 UID 极差不超过 2 ^ 30 (约 10 亿 7300 万),bitmap 只需要 128 MB 内存 /磁盘
2022-07-10 21:43:06 +08:00
回复了 wanchenyi 创建的主题 问与答 shell 脚本求指点
@wanchenyi 8 楼的应该还不是完整的答案,除非:

1. 不要最后一组数据了
2. 保证 name 和 id 里的值不会出现一些如 $ ` 的特殊字符,否则会出现任意执行代码漏洞

如 id: "恶意代码:$(sleep 300)" 可以让你的 shell 卡五分钟
2022-07-10 19:26:59 +08:00
回复了 reymond3 创建的主题 问与答 寻找类似数据库的文件管理软件, window 平台下。
靠,tree 还用了不是普通空格的空格。。
2022-07-10 19:23:43 +08:00
回复了 reymond3 创建的主题 问与答 寻找类似数据库的文件管理软件, window 平台下。
上面写漏了,应该是:

/
├── 归档
│   ├── A 项目 6 月份月报.docx
│   ├── A 项目 7 月份月报.docx
│   ├── B 项目 6 月份月报.docx
│   └── B 项目 7 月份月报.docx
├── 月份
│   ├── 6
│   │   ├── A 项目月报.docx.lnk
│   │   └── B 项目月报.docx.lnk
│   └── 7
│     ├── A 项目月报.docx.lnk
│     └── B 项目月报.docx.lnk
└── 项目
  ├── A
  │   ├── 6 月份月报.docx.lnk
  │   ├── 7 月份月报.docx.lnk
  │   └── (如果在此新建“8 月份月报.docx”,自动移到“归档 /A 项目 8 月份月报.docx”,此处变成“8 月份月报.docx.lnk”)
  └── B
    ├── 6 月份月报.docx.lnk
    └── 7 月份月报.docx.lnk
2022-07-10 19:17:15 +08:00
回复了 reymond3 创建的主题 问与答 寻找类似数据库的文件管理软件, window 平台下。
感觉你说的第二点可行。写个小脚本,对现存的文件自动生成快捷方式 /软链接 /硬链接,咋样?

如现存文件:
A 项目 6 月份月报.docx
A 项目 7 月份月报.docx
B 项目 6 月份月报.docx
B 项目 7 月份月报.docx

自动生成(把两个半角空格转成一个全角了,不知道还会不会吞空格):

├── 月份
│  ├── 6
│  │  └── A 项目月报.docx.lnk
│  └── 7
│    └── B 项目月报.docx.lnk
└── 项目
  ├── A
  │  └── 6 月份月报.docx.lnk
  └── B
    └── 7 月份月报.docx.lnk

如果在某个生成的目录中增加 /重命名 /修改文件,也自动同步回归档目录中?
2022-07-10 14:11:36 +08:00
回复了 wanchenyi 创建的主题 问与答 shell 脚本求指点
@ruidoBlanco 我是 v 站 新人,不太熟悉这儿的风气,不知道回答问题是否该考虑全一点,还是大致给个方向即可

我觉得,字符串里有 " 是合理且可预见的情况,还是该做处理的,仍属于帖子“提取对应值”主题范畴

(所以,只是“答得有没有更全面一点”的区别?)

“name 可以有重复”,这是上一层的工作了吧。另外,楼主也说了“每个 name 和 id 是不一样的”
2022-07-10 11:37:45 +08:00
回复了 wanchenyi 创建的主题 问与答 shell 脚本求指点
@ruidoBlanco

按 " 分割的话,值包含 " 就不好办了( name: "my name is \"xxx\"")

另外,最后一行不是------的话,最后一组值也没了
2022-07-10 11:28:12 +08:00
回复了 wanchenyi 创建的主题 问与答 shell 脚本求指点
不懂 awk 如何限制最多分割的列数(比如,按“:”分割,最多两列,最后一列可以包含任意个“:”),只能用正则来匹配了

假设 name 或 id 的值符合 json 的字符串规范

awk -v FPAT='(\\w+)|:|"(\\\\?.)*"' 'function output_dict() {if (length(dict)) {printf "%s\0%s\0", dict["name"], dict["id"]; delete dict }} /^\w/{dict[$1]=$3} /^-/{output_dict()} END{output_dict()}' | xargs -0 -n 2 echo


[输入]
name: "name1"
id: "id1"
------
id: "\"id2\": "
name: ": \"name2\""


[输出(要由后面的命令去转义了)]
"name1" "id1"
": \"name2\"" "\"id2\": "


[实际执行]
echo '"name1"' '"id1"'
echo '": \"name2\""' '"\"id2\": "'
2022-06-28 19:04:41 +08:00
回复了 jackiejkl 创建的主题 MySQL 请问如果一棵树存在数据表中,有没有办法将其一次查出?
@kkkiio 树结构庞大,CTE 比不过原因是啥?查 parent_id 索引难命中缓存?

那加个 root_id 字段,索引 (root_id, parent_id),是不是同一棵树的索引都尽量集中到一块儿去就好了
2022-06-28 18:35:28 +08:00
回复了 jackiejkl 创建的主题 MySQL 请问如果一棵树存在数据表中,有没有办法将其一次查出?
@n0trace 邻接表类型,移动节点,不是一条 update xxx set parent_id = ? 即可吗
2022-06-28 13:43:06 +08:00
回复了 jackiejkl 创建的主题 MySQL 请问如果一棵树存在数据表中,有没有办法将其一次查出?
为毛缩进全没了
2022-06-28 13:39:57 +08:00
回复了 jackiejkl 创建的主题 MySQL 请问如果一棵树存在数据表中,有没有办法将其一次查出?
数据库新手,拿 SQLite 练练 CTE

实现了一条语句将 json:

{"书": {"章 1": ["节 1", "节 2"], "章 2": "节 3"}}

逐项添加进表中:

+----+-----------+------+
| id | parent_id | data |
+----+-----------+------+
| 2 | 0 | 书 |
| 4 | 2 | 章 1 |
| 5 | 4 | 节 1 |
| 6 | 4 | 节 2 |
| 7 | 2 | 章 2 |
| 8 | 7 | 节 3 |
+----+-----------+------+

再用一条语句,将某节点(如“节 2”)所在的整棵树查询出来:

+-----------+
| result |
+-----------+
| 书 |
| 章 1 |
| 节 1 |
| 节 2 |
| 章 2 |
| 节 3 |
+-----------+

功力不够,想转化成 json ,却不懂咋写了


CREATE TABLE node (id INTEGER PRIMARY KEY, parent_id INT, data);
INSERT INTO node (parent_id, data) VALUES (0, '书 0'); -- 测试表非空时 下面 INSERT 是否正常

-- =================================
-- 以下将 json 字符串 逐项添加进表中
-- =================================

WITH
my_data(json) AS (
SELECT '{
"书 1": {
"书 1 章 1": ["书 1 章 1 节 1", "书 1 章 1 节 2"],
"书 1 章 2": {
"书 1 章 2 节 1": {"书 1 章 2 节 1 段 1": "书 1 章 2 节 1 段 1 字 1"},
"书 1 章 2 节 2": ["书 1 章 2 节 2 段 1", "书 1 章 2 节 2 段 2"]
}
},
"书 2": ["书 2 章 1", "书 2 章 2"]
}'
),

node_info(max_id) AS (
SELECT IFNULL(max(id), 0) FROM node
)

-- 添加搜集好的 key 和 value
INSERT INTO node (id, parent_id, data)

-- 遇到 object 时,取其 key
SELECT max_id + id - (type NOT IN ('array', 'object')) AS id,
CASE WHEN parent THEN max_id + parent
ELSE 0
END AS parent_id,
key AS data
FROM node_info, my_data, json_tree(my_data.json)
WHERE typeof(key) = 'text'
UNION ALL

-- 不是 array 和 object 时,取其 value
SELECT max_id + id + (parent = 0 AND key IS NULL) AS id,
CASE WHEN typeof(key) = 'text' THEN max_id + id - 1 -- object 的值
WHEN parent THEN max_id + parent -- array 的值
ELSE 0 -- 根处的值
END AS parent_id,
value AS data
FROM node_info, my_data, json_tree(my_data.json)
WHERE type NOT IN ('array', 'object');

SELECT * FROM node;

-- =====================================================
-- 以下将 某节点所在的整棵树 转化成 有缩进的列表 和 json
-- =====================================================

WITH RECURSIVE
my_data(node_id) AS (
SELECT id FROM node WHERE data = '书 1 章 2 节 1 段 1 字 1' LIMIT 1
),

-- 列举 my_data 的 node_id 的所有父节点
parent_of(id, parent_id) AS (
SELECT id, parent_id
FROM my_data JOIN node ON node_id = node.id
UNION ALL
SELECT p.id, p.parent_id
FROM parent_of n JOIN node p ON n.parent_id = p.id
),

-- 获取 my_data 的 node_id 的根节点
root(id) AS (
SELECT id FROM parent_of WHERE parent_id = 0
),

-- 列举 tree
list(id, data, level) AS (
SELECT id, data, 0
FROM root JOIN node USING(id)
UNION ALL
SELECT n.id, n.data, level + 1
FROM node n JOIN list p ON n.parent_id = p.id
ORDER BY 3 DESC, 1
)

-- -- json 化 tree
-- jsonify() AS (
-- -- 功力不够,写不出来
-- )

SELECT format('%*s', level*3, '') || data FROM list;
2022-06-28 01:33:57 +08:00
回复了 jackiejkl 创建的主题 MySQL 请问如果一棵树存在数据表中,有没有办法将其一次查出?
(递归) Common Table Expressions ?深度广度优先搜索都可
1 ... 24  25  26  27  28  29  30  31  32  33  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2649 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 22ms · UTC 04:33 · PVG 12:33 · LAX 20:33 · JFK 23:33
Developed with CodeLauncher
♥ Do have faith in what you're doing.