65.9K
CodeProject 正在变化。 阅读更多。
Home

NoSQL 还是不 NoSQL?

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.84/5 (53投票s)

2016年12月6日

CC (Attr 3U)

24分钟阅读

viewsIcon

60917

downloadIcon

378

这是一个问题。本文将对这两种技术进行比较,并提供一些选择最适合您需求的建议。

引言

在过去的几年里,我们见证了 NoSQL 技术的兴起,它被应用于越来越多的应用程序中。本文旨在对 SQL 和 NoSQL 技术进行客观比较,并试图澄清一些不明确的方面,以帮助人们明智地选择其后端。

目录

  1. 什么是 NoSQL
  2. NoSQL 实现
  3. NoSQL 的优势
  4. NoSQL 的局限性
  5. 性能对比
  6. 关注点
  7. 历史

什么是 NoSQL

简单来说,NoSQL 是一种不遵循关系型数据库模型的新数据存储后端。这意味着我们谈论的是一个与传统基于 SQL 的后端工作方式不同的“容器”。
NoSQL 技术是为了满足传统数据库已经成熟时出现的一系列新需求而诞生的。当然,在过去的几年里,应用程序需要改变并变得越来越挑剔(大数据、集群、文件存储库),因此这种新的存储系统在设计时就考虑到了这些新要求。

但是,“需求”是什么意思?以下是 NoSQL 设计用于支持的一些案例。

  • 应用程序处理大量数据(大数据)
  • 应用程序处理关系和数据类型快速变化的数据(半结构化、非结构化和多态数据)
  • 开发人员在小型团队中使用敏捷方法:许多短冲刺而不是长期的瀑布式迭代
  • 应用程序作为服务提供,可能会发布到网络上
  • 应用程序提供给数千名用户,而不是公司内部的少数人
  • 不确定应用程序未来的负载:需要可扩展和动态,需要轻松地在后端集群上搭建基础软件

市场上有许多 NoSQL 解决方案,无论是开源还是非开源。它们中的每一个工作方式都略有不同,可能专门用于某些特定需求,但基本思想和共同特征是提供更好的可扩展性和性能。为此,它们放弃了通用 RDBMS 的一些功能,引入了新的功能,但保留了足够的功能以保持有用。

NoSQL 实现

SQL 数据库的一个重大变化是,SQL 后端是通用存储系统,而 NoSQL 分布则专注于特定类型的数据。这使得数据库在其范围内更高效,并允许拥有更高性能的系统。在本节中,将介绍一些 NoSQL 数据库的类型,以了解它们的应用。请注意,它们可以一起使用(也可以与传统 SQL 系统一起使用),以从所有系统中获得最佳效果。

面向文档

这种类型的数据库不需要一致的数据结构,因此当您必须处理多态数据或数据结构不断变化时,它们非常有用。这种后端可以将键值数据集或 EAV 模型等规范化实体转换为简单的文档集。

  • 目标:存储非类型化的“记录”集,称为“文档”
  • 示例:MongoDB、CouchDB
  • 目标:异构数据、面向对象工作、敏捷开发

图数据库

我们被告知 NoSQL 数据库消除了关系概念以实现更好的性能。在这种数据库中,情况并非如此。相反,这些数据库加强了关系的概念。

它们的目标是通过数据与其他数据的关系来定义数据。当大多数数据结构旨在保持与实体的关系时(即,如果您有很多表,其中主要是外键列),这种数据库会很有用。

  • 目标:描述数据关系
  • 示例:Neo4j、GiraffeDB
  • 目标:数据挖掘

键值存储

这是一种旨在存储大量键值对数据的数据库。当数据库用于存储属性、翻译或缓存目的时,这会很有用。

  • 目标:以键值形式存储数据
  • 示例:Redis、Cassandra、MemcacheDB
  • 目标:键值存储

NoSQL 的优势

我们知道 NoSQL 数据库具有一些有趣的优势,并且它们可以轻松解决传统 RDMS 无法解决的简单问题。如今,它们在关键系统(如大型云系统和一些大型 SaaS 产品)中的广泛应用证实了它们的成熟和有用。但问题是,我为什么要转向它们?在这种情况下,何时转向有利可图?我们不能仅仅根据我们的印象做出这样的决定,阅读一些声称 NoSQL 非常酷的供应商手册是不够的。此外,我们不能仅仅因为害怕改变而停留在不合适的平台上。

在本章中,我将尝试解释为什么这个解决方案可能足以转向它,以及哪些用例使其更有利可图。

正如我们所说,NoSQL 数据库是为了响应传统关系数据库技术的局限性而创建的。这意味着我们会发现一些改进,或者更好的是,传统关系数据库中不存在也无法添加的一些功能,即使生产者愿意实现它们。

NoSQL 的优势包括轻松处理以下能力:

  • 大数据:这个术语描述了包含大量数据的数据集。
  • 可变数据:数据可以是结构化的、半结构化的和非结构化的。NoSQL 还可以管理数据转换。
  • 动态开发:在需要敏捷冲刺、快速迭代、频繁代码推送以及总而言之对变化做出响应的环境中,拥有一个支持动态的数据库非常有用。
  • 面向对象:易于使用且灵活的编程
  • 可扩展:我们可以轻松实现高效、可扩展的架构,而不是昂贵、单一的架构。即使在传统数据库中,我们也可以这样做,但它更难且有限。
  • 开源:大多数解决方案都是开源的,因此无需许可费用。

总结

NoSQL 数据库更具可扩展性,并提供更好的性能,其数据模型更接近应用程序内部使用的领域模型。如今,基于 NoSQL 数据库启动项目的公司正在增长。NoSQL 数据库也倾向于开源,这意味着开发、实现和共享软件的成本相对较低。

NoSQL 的局限性

在评估 NoSQL 数据库的局限性时,重要的是要记住 NoSQL 世界是一个多样化的生态系统。并非所有 NoSQL 存储产品都受到所有缺点相同程度的影响。这是一件好事,因为这意味着组织在权衡不同 NoSQL 解决方案的优缺点以决定哪一个最适合其特定需求时,有很多选择。本章总结了使用 NoSQL 解决方案可能会错过的一些功能。

通过阅读本文,您会发现本章比优点部分扩展得更多。这并不是为了劝退使用 NoSQL。本章将公正地描述 NoSQL 技术的所有限制,只是想让您了解在使用它们时可能遇到的所有问题。许多点可能会因实现而异(例如,当我说支持工具很少时,这可能适用于大多数但并非所有),因此请将它们视为一个概述,它将提醒您可能遇到的风险。我希望您在选择要使用的 NoSQL 产品后,可以将本章作为清单,以了解这些问题是否存在于您的特定数据库中以及它们是否与应用程序相关。

安全

安全是每个人都想要但难以实现的东西。理论上,每种技术都可能存在安全问题。SQL 系统也存在安全问题,也许现在仍然存在。那么,我为什么将此标记为 NoSQL 上可能的问题?NoSQL “概念”本身与安全没有真正的关联问题,但我们可能面临与所用产品成熟度相关的安全问题。安全问题随着产品的增长而出现并得到修复。直观地说,一个年轻的产品可能存在许多未知的安全问题。此外,年轻的产品上市时间短,因此顾问没有时间积累经验,许多安全限制可能会被忽视。因此,问题在于大多数 NoSQL 平台的年轻化。对于商业用途,我建议只使用成熟的解决方案,并有供应商支持。

数据一致性

当我们开始学习 RDBMS 时,他们告诉我们 ACID 事务是使操作在整个数据库中保持一致的最佳选择。然而,大多数 NoSQL 技术并没有实现这种类型的事务。NoSQL 系统基于最终一致性原则。实际上,它们通过承担一些一致性风险(一个节点可能与其他节点不同步)来获得一些性能提升。是的,这是一种权衡,但我们不能拥有一切。

我不得不提到,一些 NoSQL 实现,如 FoundationDB,允许类似 ACID 的事务,同时保持 NoSQL 性能高。无论如何,当我们停留在 NoSQL 上时,数据一致性仍然是关键部分:根据您正在开发的应用程序,这可能是一个问题,也可能不是。

JOIN

当您与试图将您转换为 NoSQL 技术的人交谈时,您可能会从他们那里听到的第一个好处是由于删除关系而带来的性能优势。我们所有人都同意关系可能会导致性能下降,但删除它们我们会失去什么呢?这就像您背着一个又大又重的背包在山路上攀爬。当然,放下它您会走得更快。这样做方便吗?这取决于背包里装了什么,取决于背包内容对您的价值。如果它装了晚上用的帐篷,那么也许晚一个小时到达目的地但睡个暖和的觉会更好,而不是走得更快。如果您带着有用的可丢弃物品,也许您可以做相反的事情。

以此类推,我们能接受为了性能而失去一致性吗?这样做方便吗?

退一步说,我将从连接的起源开始。RDBMS 使用关系将数据从一个表链接到另一个表,以将数据保存在一个地方并且不复制它们。`Join` 是一个构造,允许在查询中重新连接它们。当然,在表之间进行连接会产生额外的计算成本,相对于直接在您查询的表中查找数据。但这种成本对于保持关系(不复制,一致性)是必要的。

很明显,当这种构造的开销可以接受时,这是可以的,并且可能是最佳选择。但是当它拖慢一切或需要太多硬件时呢?这个问题让 NoSQL 开发人员将缺少 `JOIN` 视为一个特性,但 NoSQL 是解决方案吗?

不总是。有时,我们只需要重新设计数据库结构,也许删除一些关系或重新组织数据。是的,我们会失去一些关系或者我们会复制部分日期,但这可能是可以接受的(在 NoSQL 中,我们将失去所有的关系)。

另一个问题是与一致性有关。考虑类别和产品。我们可能有一个嵌套的类别树,其中有许多产品作为树的叶子。在传统的 RDMS 中,更改类别树只是对 `category` 表上的外键(自关系)进行更新。这些更改会自动反映到所有子类别和产品上。在 NoSQL 方式中,我们可能在所有类别/产品中都有冗余数据,并且更改将需要对子元素进行大量更新。

棘手的事务

假设我们的应用程序可以放弃 `JOIN` 以获得速度,并且在我们的案例中,这是一个可以接受的权衡。我们已经说过,在许多 NoSQL 实现中,很难保持各种条目的一致性。当您在没有事务的情况下工作时,您可以按顺序执行许多操作,但崩溃后,您会得到不一致。这对于 NoSQL 的早期实现是正确的,一些新技术试图提供开箱即用的事务。您还可以考虑在应用程序级别管理事务,尝试回滚脏数据,但在许多情况下可能很难管理。

供应商技术之间缺少标准

SQL 是一种标准语言。可能有很多变体导致特定的方言,但这很复杂,并不能阻止抽象数据访问。想想 Hibernate、NHibernate、Doctrine、Entity Framework 或您喜欢的其他 ORM:它们证明了区分 SQL 方言并不那么重要。我们可以得出结论,SQL 是一种标准语言,即使许多供应商实现不同的数据库技术。即使您不基于 ORM 层,如果您为数据库生成查询,大部分代码也可以在其他数据库中重用。这使得迁移更容易,开发人员可以快速适应不同的数据库解决方案。

另一方面,在 NoSQL 世界中,有更多的混乱。每个供应商都实现自己的特定语法,不涉及任何共享标准。这意味着在不同的 NoSQL 实现之间迁移应用程序更困难。这意味着更难找到一个精通多种 NoSQL 技术的程序员。

架构灵活性可能成为一个麻烦

NoSQL 系统的一个特点是它们不需要 schema。实际上,是程序员在保存数据时决定数据结构。因此,没有地方写明数据是如何构造的或数据的含义是什么。即使您可以使用一些自动化工具轻松地从数据关系开始重新创建数据库模型,这在传统应用程序中也可能缺失。此外,如果发生 bug 怎么办?我们知道代码可能存在错误的情况。传统 RDBMS 是搭建好的,因此如果您切换某些字段或字段格式错误,它们会保护您免受不一致的影响。在 NoSQL 的情况下,数据库没有任何帮助,因为没有定义任何 schema,也没有关于数据应该如何保存的信息:没有人能说数据是对还是错。最糟糕的副作用是这个过程给开发人员带来了很大的权力和责任,而开发人员往往不了解所有过程或结构。

此外,即使您现在知道在哪里保存了什么,您认为下个月还会记得所有内容吗?明年呢?并非所有项目都持续开发,有些业务应用程序可能会保持现状一年,然后才需要进行一些更改。无论如何,在 IT 领域,公司经常将项目委托给某些供应商,因此这部分必须考虑在内,以确保项目结束时易于交接,也许需要对数据结构和每个字段/集合的含义进行准确的文档说明。与 schema 灵活性相关的最后一个问题是,团队的每个成员可能不会在项目的整个生命周期中工作,因此在小型团队中,如果并非所有成员都完全了解数据结构或没有足够的文档,人员流动至关重要。

分析

将大量嵌套数据保存在单个文档中,您可能会丢失“`SUM`”、“`COUNT`”等分析功能。糟糕的是,这在首次应用程序开发期间可能不是问题,但有人可能会稍后要求提供一些报告,那么在这种情况下该怎么办?在数据库填充后更改数据结构很困难,并且由于缺乏明确定义的数据结构,这样做可能会产生许多不可预测的影响。分析是 NoSQL 的一个难点。

此外,虽然有许多商业工具可以连接到您的传统数据库以管理分析部分,但对 NoSQL 系统的支持有限。

另一种解决方案是,在 NoSQL 数据库中,使用非结构化数据复制某种“关系”,例如创建许多集合并将对象彼此链接。如果您计划走这条路以允许分析报告,请记住这可能会降低性能,使其与标准 SQL 系统相媲美。当涉及此数据库的部分最少且记录计数有限时,这可能是可以接受的。无论如何,即使根据我的经验,在 NoSQL 查询上允许连接数据的构造也非常有限,因为背后没有明确定义的关系,并且性能不如我们预期(即,在撰写本文时,MongoDB 不支持内连接,并且只能每次演变为一个表而无需创建临时表)。

更少的工具

我们谈到了 NoSQL 查询语言和语法的缺乏标准化。这个问题也可能反映在工具上,以及大多数平台的年轻化。我指的是用于查询的工具,也包括用于在数据库之间迁移数据、管理备份等的工具。当然,大多数 NoSQL 项目都在增长,我们期望工具也会随之增长,因此这个问题将在不久的将来自动解决。

缺乏标准化使得第三方供应商难以构建支持多种 NoSQL 解决方案的工具。此外,年轻的平台意味着更少的用户、更少的客户以及更少的时间来开发成熟的工具。

性能比较

重要的是要说明比较是如何进行的。首先,我需要将两种解决方案置于相同条件下。这意味着,例如使用相同的硬件并具有相同的调优级别。因此,我在同一台机器上安装了 MongoDB(最新版本)和 SQLServer Express。因为我们对数据库本身的性能不感兴趣,所以我使用基于标准框架的 C# 代码构建了我的基准测试。在这两种数据保存方式之上,所有内容(实体、逻辑、数据生成)都是共享的,以确保公平性。

基准详情

功能 NoSQL SQL
CPU i7 i7
RAM 16GB 16GB
磁盘 固态硬盘 固态硬盘

我们将比较所有操作的列表

  • 批量插入
  • 查询
  • 分析
  • 事务(或者更好的是,在 NoSQL 案例中,事务模拟)

对单个实体的批量操作

此基准测试包含大量要插入的对象,需要在尽可能短的时间内完成。此测试使用不断增长的要保存的项目数量进行复制,以证明两个系统中的性能如何扩展。此基准测试以毫秒为单位测量执行时间,并作用于单个表/集合。

性能对比

行数 NoSQL(毫秒) SQL(毫秒)
100 1 3
1000 12 163
10000 85 202
100000 842 2182
1000000 9179 19875

SQL NoSQL Comparison

搜索

此基准测试侧重于查询功能。我们区分以下模式:

  • 案例1 使用主键获取一个实体:此模式用于使用其唯一标识符从数据库中获取单个实体。
  • 案例2 带失败的全表扫描:当您查找已删除的元素并且数据库必须扫描所有索引然后回复“无”时。
  • 案例3 分页查询:一个复杂的查询,您有一些过滤器、一个排序条件,并且您只想获取一页数据。

我创建了一些基准测试,模拟上述不同比例的模式。例如,第一个基准测试假设 5% 的查询是第 1 种,70% 是第 2 种,25% 是第 3 种。此基准测试以毫秒为单位测量执行时间。此基准测试作用于单个表/集合。

您可以在 github 上找到用于执行这些测试的所有代码。

基准描述

  案例 1 案例 2 案例 3
基准 1 5% 70% 25%
基准 2 10% 45% 45%
基准 3 15% 8% 77%

第一次测试是在一个“小”数据集上,大约 2,500,000 行。

性能对比

基准 NoSQL(毫秒) SQL(毫秒)
基准 1 47 244
基准 2 1 13
基准 3 1 12

第二个测试是在一个“更大”的数据集上,大约 5M 行。

性能对比

基准 NoSQL(毫秒) SQL(毫秒)
基准 1 56 287
基准 2 2 17
基准 3 2 18

此基准测试突出显示了查询在索引上的性能有很大提升,但当 MongoDB 用于读取数据集时,收益会减少并随着数据增加而保持稳定。

事务

我们知道 NoSQL 世界中的事务大多不被支持。我们也明白放弃事务可能会带来性能上的好处,问题是:我能从中获得多少?我创建了这个基准来比较在一个主行与多个子行相关的事务中插入。基准侧重于执行时间,以毫秒表示。

性能对比

事务数 SQL(毫秒) NoSQL(毫秒)
10 99 89
100 1004 764
1000 11025 7309

分析

此基准测试侧重于分析。假设我们有一个分类的主从数据模型,您想要:

  • 导出:整个数据树的完整连接
  • 报告:计算所有类别中所有项目的总和,即,为所有客户提供发票金额
  • KPI:汇总所有主表总计,汇总明细小计

在内连接后有 4M 行数据的基础上

性能对比

测试 SQL(毫秒) NoSQL(毫秒)
KPI 1176 1403
报告 805 1363

Analytics compariso SQL NoSQL

关注点

在科技领域,变革是不可避免的。一项新技术出现并带来一些革命性的功能,但往往必须克服开发人员的先入之见。有时,它们被误解,以至于在被使用后才暴露出弱点。

关于创新,我们有“对立”的两类人:

  1. “热情”的人,他们无条件地拥抱变革,并准备好抛弃过去所做的一切,以使用最新的技术;
  2. “保守”的人,他们讨厌变化,宁愿墨守成规,拒绝任何新技术。

在现实生活中,我们必须保持中立,因此了解和理解新技术能为我们做什么,并准备在项目需要之前采用新技术是很重要的。“边做边学”是一种不好的习惯,可能会导致糟糕的结果。

同样的原则也适用于 NoSQL 技术。由于我们以前研究过 NoSQL,现在我们了解了它的优缺点,因此我们可以利用这种工具。当我们分析这项技术时,我们不能仅仅关注我们传统习惯中缺失的东西,比如事务、架构和标准。我们需要学习并熟悉这些技术,它们直到几年前还很年轻和新颖,但现在是一个切实的选择。学习、掌握、理解、运用:这就是进步的本质。

我何时应该使用 NoSQL 数据库?

为什么 NoSQL 会比使用 SQL 数据库更好?阅读本文后,我相信您会明白 NoSQL 并非 SQL 数据库的替代品,而是一种具有不同功能且在某些特定领域有用的不同存储系统。因此,答案只能是“视情况而定”。因为它确实取决于项目的许多特点。

老实说,谨慎地说,当以下所有陈述都为真时,NoSQL 是最佳解决方案:

  • 当您的项目需要扩展,或者未来可能会扩展时。
  • 当您必须处理大数据,或者您的数据在不久的将来会很大时。
  • 当应用程序中的分析组件很简单,或者不是那么重要时。
  • 当您的应用程序需要符合数据库用途时(例如,您正在以图的形式保存数据,并且数据库也这样做)。

在某些情况下,NoSQL 可能是一个不错的替代方案,但它对于构建持久基础设施并非必不可少。当然,如果您的应用程序中 NoSQL 系统覆盖了所有需求的 99%,那么没有理由将其与 RDBMS 耦合。但是,如果您需要关系、事务以及标准 RDBMS 的其他功能,那么最好将其用作主要存储系统,并仅使用 NoSQL 来覆盖关键部分(可能根据数据大小衍生)。

在上述情况下,性能提升了多少?

这取决于具体的用例。一方面,在大表或大量使用方面我们有很多好处,但另一方面,在小数据集上使用查找而不是连接会损失一些性能。一个现实的估计是,如果存在使用 NoSQL 数据库的基础,我们可以将性能提高 10 到 100 倍。当然,这个估计考虑了应用程序的所有方面,并且与最终用户体验相关。这意味着您可以在数据库层测量到更好的加速,但最终用户体验受到许多因素的影响,这些因素会缩小差距(缓存、网络延迟、页面渲染)。为了解释我所说的,举一个极端情况:有一个页面进行查询并返回数据。假设此页面使用传统数据库获取结果需要 500 毫秒,使用 NoSQL 需要 50 毫秒,渲染页面需要 200 毫秒,通过互联网传输数据需要 1 秒。数据库层的性能提升是 -90%,但对于最终用户来说,在 1700 毫秒中只节省了 450 毫秒,因此只有 26%。通过这个例子,我想说明的是,在复杂系统中很难衡量性能提升,在许多情况下,NoSQL 不足以解决性能问题。更直接地说,如果您认为通过转向 NoSQL 可以解决应用程序中由于糟糕设计导致的性能问题,那么您就走错了路。

但最大的问题是:为了获得这种性能,我失去了什么?因为在某些情况下,不可能放弃某些功能,例如事务或关系。在做出决定之前,这一点非常重要。

NoSQL 系统是否成熟到可以在生产环境中使用?

主要取决于您的需求,或者更确切地说是项目要求。我们可以说 NoSQL 肯定已经足够成熟可以使用了。所以,如果您需要,您可以毫无畏惧地使用它。但并非所有应用程序都需要处理大数据或大规模扩展。大多数 SaaS 产品都是如此,企业环境中的许多关键应用程序也是如此,但如今大多数应用程序仍然非常简单。根据我的经验,在数据库中很难找到超过 100,000 行的表。想想您的数据库,排除其中 2-3 个较大的表,然后查看行数。它们有多大?数据库应用程序中常见的数据库结构包含许多相互关联的“小”表(少于 100,000 行)。对于这种应用程序,传统的 RDBMS 已经足够,并且将永远足够。重要的是,不是开始使用它,而是了解其优势和开发模式,以便在需要时做好准备。

SQL 过时了吗?

当人类发明飞机时,汽车就过时了吗?不,当然没有。即使飞机比汽车快,它们也只是两种不同的交通工具,具有不同的特点。根据您即将开始的旅程类型、您需要花费在旅途上的时间以及预算,您将决定哪种替代方案最适合您。同样,NoSQL 的出现并没有使 SQL 过时。它们只是两种不同的数据存储方式,具有不同的特点。您将根据您的需求决定哪种最适合您。

有些问题 SQL 不适合解决,所以你不必用它来启动大数据项目。这就像试图用汽车而不是飞机到达一个岛屿。但是 SQL 仍然有它的优势。许多数据模型最好表示为相互引用的表集合。这就像试图用飞机去买牛奶。NoSQL 数据库不是 SQL 的替代品,而是它的替代方案。

市场为 NoSQL 做好准备了吗?

回答这个问题的关键点更接近于开发人员所获得的经验。大多数数据库程序员被训练了一年,以关系方式思考数据。他们怎么能在这么短的时间内改变思维方式呢?这并不容易,尤其是当开发人员必须同时处理许多项目,其中一些是 SQL,另一些是 NoSQL 时。在 SQL 系统上重现相同模式到 NoSQL 系统的诱惑很难克服,并且经常导致糟糕的结果。

所以,目前 SQL 周围有更多的专业知识,擅长 RDBMS 的开发人员比擅长 NoSQL 的开发人员多。同时,有一些 DBA 将大部分时间投入到关系数据库上,我们不能期望在不到十年前诞生的技术上找到同样的情况。SQL 在学校和大学里得到讲授,NoSQL 正在开始得到讲授。

在第一点之后,第二点是,由于这些系统是新的,开发工具较少,或者它们不像其他工具那么先进,但我相信这并不是一个真正的问题。有一些“企业级”解决方案提供了管理所有基本需求的工具,我们都希望这些工具能够随着其平台的增长而发展。

最佳解决方案是什么?

没有一种最佳解决方案可以涵盖所有情况。答案很简单,而且始终如一:“视情况而定”。通过这篇文章,我希望我能为您概述这些系统的所有功能,以及了解它们何时有用的基本知识。

历史

  • 2016 年 12 月 11 日:添加了图表以比较性能
  • 2016 年 12 月 6 日:本文的第一个版本
© . All rights reserved.