什么是标签索引

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了什么是标签索引相关的知识,希望对你有一定的参考价值。

什么是标签索引?

索引: 根据一定需要,把主要内容或各种题名摘录下来,标明出处、页码,按一定次序分条排列,以供人查阅的资料。也叫“引得”。
你说的标签索引就是根据标签对内容进行的排序之后 给人查阅的序号 如果是编程的话就找找Label index相关的资料 其实以后遇到什么索引 就是指根据什么来查询 这里就是根据标签来查询。 或者目录
参考技术A 书口。

ResultSet:按索引检索列值与按标签检索

【中文标题】ResultSet:按索引检索列值与按标签检索【英文标题】:ResultSet: Retrieving column values by index versus retrieving by label 【发布时间】:2010-09-16 06:04:43 【问题描述】:

在使用 JDBC 时,我经常遇到像

这样的结构
ResultSet rs = ps.executeQuery();
while (rs.next()) 
    int id = rs.getInt(1);
    // Some other actions

我问自己(以及代码作者)为什么不使用标签来检索列值:

int id = rs.getInt("CUSTOMER_ID");

我听到的最好的解释是关于性能的。但实际上,它是否使处理速度非常快?我不相信,尽管我从未进行过测量。在我看来,即使按标签检索会慢一些,但它提供了更好的可读性和灵活性。 那么有人可以给我很好的解释来避免通过列索引而不是列标签来检索列值吗?两种方法的优缺点是什么(也许,关于某些 DBMS)?

【问题讨论】:

有什么常量可以使用吗?类似'ResultSet.CUSTOMER_ID' 【参考方案1】:

警告:我要在这里夸夸其谈,因为这让我发疯。

99%* 的时间里,人们有一些模糊的想法让事情变得“更好”,这是一种荒谬的微优化。这完全忽略了这样一个事实,即除非您一直处于极其紧张和忙碌的循环中,处理数以百万计的 SQL 结果(希望这种情况很少见),否则您永远不会注意到它。对于所有不这样做的人来说,开发人员维护、更新和修复列索引中的错误的时间成本远远大于性能极差的应用程序的硬件增量成本。

不要为这样的优化编写代码。为维护它的人编写代码。然后观察、测量、分析和优化。再观察,再测量,再分析,再优化。

优化几乎是开发的最后一步,而不是第一步。

* 图是编出来的。

【讨论】:

没有。绝对不。我讨厌人们谈论预优化的方式。 Java 是一种安全的语言——它不是意大利面条代码的许可证。您仍然应该注意 Java 规范和语法,以及您正在使用的任何其他 API 或规范。当你在写一个 1000 行的微程序时,你可以做出这样的让步,那么当然——去吧。但任何比这更大的事情并在实际产品上工作,您最好 100% 了解您正在编写的代码的含义,并且您最好能够解释为什么这种性能损失是可以接受的。【参考方案2】:

您应该默认使用字符串标签。

优点:

列顺序的独立性 更好的可读性/可维护性

缺点:

您无法控制列名(通过存储过程访问)

你更喜欢哪个?

整数?

int i = 1;  
customerId = resultSet.getInt(i++);  
customerName = resultSet.getString(i++);  
customerAddress = resultSet.getString(i++);

还是字符串?

customerId = resultSet.getInt("customer_id");  
customerName = resultSet.getString("customer_name");  
customerAddress = resultSet.getString("customer_address");

如果在位置 1 插入了新列怎么办?你更喜欢哪个代码?或者如果列的顺序改变了,你需要改变哪个代码版本?

这就是为什么你应该默认使用字符串标签。

【讨论】:

始终使用字符串作为您的首选,当您只是将文件转储到 CSV 时,有一个地方基于索引的访问是有意义的,但是这里需要注意的是所有列都必须转储为字符串。 嗯,这甚至​​没有回答这个问题。这是怎么得到这么多赞成票的?如果你要抛出这样的东西,那很好(在很多情况下我什至很感激),但至少要回答最初的问题。【参考方案3】:

答案已被接受,不过,这里有一些我还没有看到提出的补充信息和个人经验。

如果可能,一般使用列名(最好使用常量而不是文字)。这既更清晰,更易于维护,而且未来的更改不太可能破坏代码。

但是,列索引有一个用途。在某些情况下,这些速度更快,但不足以覆盖上述名称的原因*。这些在开发处理ResultSets 的工具和通用方法时非常有价值。最后,可能需要索引,因为该列没有名称(例如未命名的聚合)或存在重复名称,因此没有简单的方法来引用两者。

*请注意,我编写了一些 JDBC 驱动程序并查看了一些开源驱动程序,并且在内部这些驱动程序使用列索引来引用结果列。在我使用过的所有情况下,内部驱动程序首先将列名映射到索引。因此,您可以很容易地看到,在所有这些情况下,列名总是需要更长的时间。不过,这可能不适用于所有驱动程序。

【讨论】:

【参考方案4】:

来自 java 文档:

ResultSet 接口提供用于从当前行检索列值的 getter 方法(getBoolean、getLong 等)。可以使用列的索引号或列的名称来检索值。一般来说,使用列索引会更有效。列从 1 开始编号。为了获得最大的可移植性,每行中的结果集列应按从左到右的顺序读取,并且每列只能读取一次。

当然,每种方法(命名或索引)都有它的位置。我同意命名列应该是默认值。但是,在需要大量循环并且 SELECT 语句在同一段代码(或类)中定义和维护的情况下,索引应该没问题 - 建议列出正在选择的列,而不仅仅是“SELECT * FROM...”,因为任何表更改都会破坏代码。

【讨论】:

【参考方案5】:

我在 Oracle 数据库上对这个确切的主题进行了一些性能分析。在我们的代码中,我们有一个包含大量列和大量行的 ResultSet。在 20 秒 (!) 中,请求执行方法 oracle.jdbc.driver.ScrollableResultSet.findColumn(String name) 大约需要 4 秒。

显然整体设计有问题,但使用索引而不是列名可能需要 4 秒的时间。

【讨论】:

【参考方案6】:

当然,使用列名可以提高可读性并简化维护。但是使用列名有另一面。如您所知,SQL 允许多个同名的列名,不能保证您在 resultSet 的 getter 方法中键入的列名实际上指向您要访问的列名。理论上,最好使用索引号而不是列名,但这会降低可读性。

【讨论】:

【参考方案7】:

你可以两全其美!使用索引的速度与使用列名的可维护性和安全性。

首先 - 除非您通过结果集循环,否则只需使用列名。

    定义一组整数变量,您将访问的每一列都有一个。变量的名称可以包括列的名称:例如iLast_Name。

    在结果集循环之前遍历列元数据并将每个整数变量的值设置为相应列名的列索引。如果“Last_Name”列的索引为 3,则将“iLast_Name”的值设置为 3。

    在结果集循环中,在 GET/SET 方法中使用整数变量名称。变量名称是开发人员/维护人员关于正在访问的实际列名称的视觉线索,但值是列索引,将提供最佳性能。

注意:初始映射(即列名到索引的映射)仅在循环之前完成一次,而不是针对循环中的每个记录和列。

【讨论】:

【参考方案8】:

我认为使用标签不会对性能产生太大影响。但是还有另一个不使用Strings 的理由。或者ints,就此而言。

考虑使用常量。使用int 常量使代码更具可读性,但也不太可能出现错误。

除了更具可读性之外,该常量还可以防止您在标签名称中输入拼写错误 - 如果您这样做,编译器会抛出错误。任何有价值的 IDE 都会选择它。如果您使用Strings 或ints,则情况并非如此。

【讨论】:

明白你的意思,但我不认为这真的有那么大的帮助。 int COLUMN_FIRST_NAME = 13; int COLUMN_SURNAME = 14;可能有错误; maye FIRST name 是 14,SURNAME 是 13。当添加列时,你仍然需要调整等等。如果你必须使用常量,我还是会使用 Strings 来避免这种情况。 int 常量解决了可读性问题,但之前的评论强调灵活性问题仍然存在。我也更喜欢字符串常量。但我没有在示例中使用常量,因为这样会让我的观点更清楚。 Rorick,我明白你的意思,我同意。但是使用常量至少可以解决可读性问题。在这两种情况下,为您想要的列使用正确的 int 问题是相同的。 如果在字符串常量中打错了会发生什么?也许你应该让每个常数成为常数?这将为您节省一些调试错误的时间【参考方案9】:

JDBC 驱动程序负责对列进行索引查找。因此,如果每次驱动程序进行查找(通常在哈希映射中)以检查列名的相应索引时,您按列名提取值。

【讨论】:

【参考方案10】:

我同意之前的回答,即性能并不是可以迫使我们选择任何一种方法的东西。最好考虑以下几点:

代码可读性:对于每个开发人员来说,阅读您的代码标签比索引更有意义。 维护:考虑 SQL 查询及其维护方式。在修复/改进/重构 SQL 查询后,您的情况更有可能发生什么:更改提取列的顺序或更改结果列名称。在我看来,更改提取列的顺序(作为在结果集中添加/删除新列的结果)更有可能发生。 封装:无论您选择哪种方式,都尝试将运行 SQL 查询和解析结果集的代码隔离在同一个组件中,并且只让该组件知道列名及其到索引的映射(如果您决定使用它们)。

【讨论】:

【参考方案11】:

使用索引是一种优化的尝试。

由此节省的时间被开发人员查找必要数据以检查其代码在更改后是否能正常工作所花费的额外精力浪费了。

我认为使用数字而不是文本是我们的本能。

【讨论】:

【参考方案12】:

除了在 Map 中查找标签之外,它还会导致额外的字符串创建。虽然它会在堆栈上发生,但它仍然需要付出代价。

这完全取决于个人的选择,到目前为止我只使用索引:-)

【讨论】:

不完全正确。字符串将来自类常量池,而不是堆栈或堆。【参考方案13】:

正如其他发帖人所指出的,我会坚持使用列名,除非您有非常充分的理由不这样做。与查询优化等相比,对性能的影响可以忽略不计。在这种情况下,维护比小幅优化更重要。

【讨论】:

以上是关于什么是标签索引的主要内容,如果未能解决你的问题,请参考以下文章

为啥 sklearn 在实现 rand 索引时需要真实标签?

为啥标签与 pandas、itertools 和 numpy 索引不一致?

如何在 iOS 中获取多个滚动视图的索引

博客园随笔中点击标签可以跳到当页指定位置的方法

PyTorch——Tensor_把索引标签转换成one-hot标签表示

如何从子页面调用 ionic 3.20 中的特定标签索引?