选择查询中,根据现有字段数据库生成实体类新字段一般书写格式是什么?

之前加入了公司的一个读书群,群规要求必须每天分享自己的读书(或其他)学习成果,在此途中,把《Effective C#》中文版读了一遍。在此把关于该书的每日分享整理一下,其实也就是个体力活儿,也算是对自己的一个回顾,也希望看到的人能有一些启发。有不足之处,还望大家多多指正,共同学习,共同进步。

第1条:优先使用隐式类型的局部变量

  • 优先使用隐式类型(var)声明局部变量,注意,是优先,不是总是。好处有:
  • var可以使开发者更多地关注在变量的命名上,而不用考虑变量的实际类型(编译器会自己推断,并选择最为合适的)。
  • 好的变量命名可以提高可读性,合适的推导类型会提高效率(例如里氏替换,你能选得过编译器?为自己省事。)
  • var并不总是合适,当涉及intfloatdouble等数值类型时,请务必明确写出。

总之,在不会发生精度损失的前提下,请务必使用隐式类型声明。

  • C#有两种常量,编译期(compile-time)常量,和运行期(runtime)常量。
  • const用来声明那些必须在编译期(静态编译?)得以确定的值,如attribute的参数、switch case语句的标签、enum的定义等,以及那些不会随版本而变化的值。除此之外的值则应该考虑声明成更加灵活的readonly常量。
  • 确实想把某个值在编译期固定下来就用const,否则就用readonly,因为其更灵活,兼容性更好。举例子,程序集A引用程序集B,程序集B中两个属性分别使用readonlyconst,若两个属性均发生更改,在不编译程序集A的情况下(只编译B,这种情况很常见),使用const声明的属性在A中调用时,并未发生改变,这就出现了兼容性问题。所以,尽量使用readonly代替const

第3条:优先考虑isas运算符,尽量少用强制类型转换

首先,在使用面向对象语言来进行编程的时候,应尽量避免类型转换操作。也许有一些场合必须使用类型转换(反思,真的是必须吗?可否绕过去?),此时应该使用isas运算符来更清晰地表达代码的意图(可读性高)。需要警惕自动类型转换(coercing type)操作,因为它们的规则各不相同,显式使用isas总能正确地表达。

如果你实在不想纠结原因,记住结论也行。

第4条:用内插字符串取代程序里面,需要回调客户端的地方应该考虑用委托来做。

第8条:用null条件运算符调用事件处理程序
  • null条件运算符为:?.
  • 比较以下三种代码的写法:
//使用null条件运算符

第一种存在空引用异常;

第二种当多线程时,可能出现空引用异常;

第三种很好,不会引发异常。原理是因为handler对Updated进行了浅拷贝(shallow copy),防止多线程空引用问题,但是这种写法新手极难看懂。

第四种,正统写法,最佳写法。首先null条件运算符左侧内容只会计算一次,其次为类型安全的Invoke()方法,而后这段代码可以安全地运行在多线程环境下。

请丢掉旧习惯,使用新方法。

第9条:尽量避免装箱与取消装箱这两种操作

  • 装箱的过程是把值类型放在非类型化的引用对象中,使得那些需要使用引用的地方也能够使用值类型。取消装箱则是把已经装箱的那个值拷贝一份出来。如果要在只接受的资源管理机制

    高效程序,需要明白内存处理与其他重要资源。.NET的内存管理与垃圾回收必须理解。

    垃圾回收(GC)来帮助你控制托管内存,无需担心内存泄漏、迷途指针(dangling pointer)、未初始化的指针以及其他很多内存管理问题。

    但是,为了防止资源泄露,非内存型资源(nonmemory resource)必须由开发者释放,于是会促使其创建finalizer来完成该工作。然而finalizer会严重影响程序的性能。

    应考虑使用IDisposable接口,以便在不给GC增加负担的前提下把这些资源清理干净。

    第12条:声明字段时,尽量直接为其设定初始值

    • 类的构造函数不止一个,构造变多了以后,开发者就可能会忘记给某些成员变量设定初始值,为了避免这个问题,最好在声明的时候直接初始化,而不要等到构造中赋值。(我之前一直觉得构造中赋值做法更正统一些,现在看来并不对。)注意,这里指的是初始值
    • 成员变量的初始化语句可以方便地取代那些本来需要放在构造器中的代码,还有一个好处是,这些语句的机器码会在本类的构造函数之前,执行的时机比基类更早。

    有三种情况不应该写初始化语句:

    1. 对象初始化为0或null(多余,降低性能);
    2. 如果属性初始值在不同的构造器中不一样,请不要写初始化语句,同样多余,降低性能;
    3. 可能存在异常的初始化语句请务必写在构造函数中,因为初始化语句不能包含在try块中,应在构造中将异常处理完毕。

    第13条:用适当的方式初始化类中的静态成员

    在创建某个类的实例对象之前,应该先把静态的成员变量初始化好。你有两种方式可以选择,一是静态初始化语句,而是静态构造函数。

    静态构造函数是特殊的函数,会在初次访问该类的其他方法、变量或属性之前执行,你可以做这么三件事,初始化静态变量、实现单例模式、其他必要的工作。

    如果静态字段的初始化工作比较复杂或是开销比较大,那么可以考虑Lazy<T>的机制,将初始化工作推迟到首次访问该字段的时候再去执行。

    静态字段初始化的原则与之前说过的成员字段初始化原则基本一致。具体参见第12条。

    要想为类中的静态成员设定初始值,最干净、最清晰的办法就是使用静态初始化语句与静态构造函数。这是C#语言对比其他语言的优点。

    第14条:尽量删减重复的初始化逻辑

    • 不要在不同的构造器中复制粘贴同样的代码!
    • 注意使用this关键字,通过链式调用构造函数,将重复的代码写到一个构造器中,再通过其他的构造器调用。
    • 采用默认参数机制来编写构造函数是比较好的做法,但是有些API会使用反射(reflection)来创建对象,它们需要依赖于无参的构造函数,这种函数与那种所有参数都具备默认值的构造函数并不是一回事,因此可能需要单独提供。
    • 构建某个类型的首个实例时系统所执行的操作(注意顺序):
    • 把存放静态变量的空间清零;
    • 执行静态变量的初始化语句;
    • 执行基类的静态构造函数;
    • 执行本类的静态构造函数;
    • 把存放实例变量的空间清零;
    • 执行实例变量的初始化语句;
    • 适当地执行基类的实例构造函数;
    • 执行本类的实例构造函数。
    • 在强调一遍,如果初始化的逻辑较为复杂,则考虑通过构造函数来实现,此时注意要把逻辑放在其中一个构造函数中,并令其他构造函数直接或间接地调用该函数,以尽量减少重复代码。(消除重复)

    第15条:不要创建无谓的对象

    • 垃圾回收器可以帮你把内存管理好,并高效地移除那些用不到的对象,但这并不是在鼓励你毫无节制地创建对象,因为创建并摧毁一个基于堆(heap-based)的对象无论如何都要比根本不生成这个对象耗费更多的处理器时间。在方法中创建很多的局部引用对象可能会大幅降低程序的性能。
    • 惰性求值算法(lazy evaluation algorithm),我觉得现在编译器就能自己优化这件事了,但是代码该写还要写。
    • 两种减少对象创建的方式:基础类库为该模式提供了两套参考实现(reference implementation)。一个是位于环境规定,这种资源并不需要由包含该资源的类型或系统来释放,而是应该由使用此类型的代码释放。
    • 拥有非托管资源的那些类型,都实现了IDisposable接口,此外还提供了finalizer(终结器/终止化器),以防用户忘记释放该资源。
    • using语句能够确保Dispose()总是可以得到调用。
    • 如果函数里只用到一个IDisposable对象,那么想要确保它总是可以能够适当地得到清理,最简单的办法就是使用using语句。
    • 对象的编译期类型必须支持IDisposable接口才能够用在using语句中,而不是任何一种对象都可以放在using里面。
    • 如果你不清楚一个对象是否实现了IDisposable接口,那么可以通过as子句来安全地处置它。using(null)不会产生任何效果,但是却可以令程序正常运行下去。
    • 凡是实现了IDisposable接口的对象都应该放在using语句中或者try块中去实现,否则就有可能泄露资源。
  • Dispose()方法并不会把对象从内存中移除,只是提供了一次机会,令其能够释放非托管型的资源。如果程序中的其他地方还需要引用该对象,就不要过早地将其释放。

第47条:专门针对应用程序创建异常

  • 如果你要给自己所写的C#应用程序创建专门的异常类,那么必须考虑的特别周到才行。
  • 必须要把那些需要用不同的方式来处理的情况设计成不同的异常类型。但是,只有那些确实需要有必要分开处理的状况才应该表示成不同的异常类,把明明可以合起来处理的情况硬是放在不同的异常类里面只会增加开发者的工作量,不能带来任何好处。
  • Exception eCLR对带有when关键字的try/catch结构做了优化,使得程序在无须进入该结构时其性能尽量不受影响。
  • 如果仅通过异常的类型不足以判断出自己到底能不能处理该异常,那么可以考虑给相关的catch子句添加筛选器,使得程序只有在筛选条件得以满足时才会进入这个catch块。

第50条:合理利用异常筛选器的副作用来实现某些效果

  • 系统在寻找catch子句的过程中会执行这些筛选器,而此时,调用栈还没有真正展开。(于是,不妨利用这一特性来实现某种效果)
  • 放在异常筛选器中的那个方法必须总是返回false,绝对不能返回true,否则异常将不会继续传播(when之后的条件为true时,将展开catch之后的子句)。你在这用情况下可以使用Expection基类作为类型,但属特例。一般情况下都应该使用Exception的子类。

还真是个体力活,又过了一遍格式,整理了一下,如果当初写的时候就精益求精,现在的话也就只要复制粘贴就行了。不过好在改的过程中,可以发现自己写得是越来越好的。学习真的是一个反人性的事情,这些时间我本可以再去看一些新的东西,但是我觉得那样会更累,于是选择了相对轻松的事情(整理之前的文档)。

希望这篇文章能对你有所帮助,欢迎相互讨论!

本文阐释如何在 Access 中创建和运行生成表查询。 需要复制表中的数据、存档数据或将查询结果另存为表格时,请使用生成表查询。

如果需要更改或更新现有记录集中的部分数据,例如一个或多个字段,可以使用更新查询。 有关更新查询的详细信息,请参阅一文。

如果需要向现有表中添加记录(行),请使用追加查询。 有关追加查询的详细信息,请参阅一文。

生成表查询可从一个或多个表中检索数据,然后将结果集加载到新表中。 新表可位于之前打开的数据库中,也可在其他数据库中创建新表。

通常,需要复制或存档数据时可创建生成表查询。 例如,假设有一张(或多张)历史销售数据表,且要在报告中使用此数据。 交易发生在至少一天以前,因此不能更改销售数据,并且通过不断运行查询来检索数据很费时,特别是对较大的数据存储运行复杂的查询时。 将数据加载到单独的表中,然后使用该表作为数据源可减少工作负荷,并方便数据存档。 处理过程中请注意,确切来说新表中的数据是一个快照;它和源表没有任何关系或联系。

创建生成表查询的过程遵循以下主要步骤:

  • 如果数据库未签名或不在受信任的位置中,则启用数据库。 否则无法运行动作查询(追加、更新和生成表查询)。

  • 在查询的“设计”视图中,创建一个选择查询,然后修改该查询,直到它返回所需的记录。 可选择多个表中的数据,且可确定地对数据执行非规范化处理。 例如,可将客户、运货商和供应商数据置于单张表中,但若生产数据库中带有适当规范化的表格,则不会执行此操作。 可在查询中使用条件来进一步自定义结果集或缩小其范围。

    有关规范化处理数据的详细信息,请参阅一文。

  • 将选择查询转换为生成表查询,选择新表的保存位置,然后运行查询以创建表。

请勿将生成表查询与更新查询或追加查询相混淆。 需要添加或更改单个字段中的数据时,请使用更新查询。 需要向现有表中的现有记录集添加记录(行)时,请使用追加查询。

若要创建生成表查询,请首先创建选择查询,然后将其转换为生成表查询。 选择查询可以使用计算字段和表达式来帮助返回所需的数据。 下面的步骤说明了如何创建和转换选择查询。 如果已经有满足需要的选择查询,则可以跳至转换选择查询和运行生成表查询的步骤。

注意: 如果已经有产生所需数据的选择查询,请转到下一节中的步骤。

  1. 在“创建”选项卡上的“查询”组中,单击“查询设计”。

  2. 双击要检索其数据的表。 每个表都显示为查询设计器上半部分的一个窗口。 添加完表后,单击“关闭”。

  3. 在每个表中,双击要在查询中使用的字段。 每个字段均显示在设计网格“字段”行中的一个空白单元格中。 下图显示的是添加了多个表字段的设计网格。

  4. (可选)向“字段”行添加任何表达式。

  5. (可选)向设计网格的“条件”行添加任何条件。

  6. 单击 运行查询,在数据表内显示结果。

  7. (可选)更改字段、表达式或条件,然后重新运行查询,直至其返回要置于新表中的数据。

  1. 在设计视图中打开选择查询,或者切换到设计视图。 Access 提供了几种执行此操作的方法:

    • 如果查询在数据表中打开,请右键单击查询的文档选项卡,然后单击“设计视图”。

    • 如果查询已关闭,请在导航窗格中右键单击该查询,然后单击快捷菜单上的“设计视图”。

  2. 在“设计”选项卡上的“查询类型”组中,单击“生成表”。

    随即显示“生成表”对话框。

  3. 在“表名称”框中,输入新表的名称。

    单击下箭头并选择现有的表名称。

      1. 如果当前数据库尚未选中,单击“当前数据库”,然后单击“确定”。

      2. 单击 " , 然后单击" "以确认操作。

        注意: 如果要替换现有表,则 Access 将首先删除该表并要求您确认删除。 单击“”,然后再次单击“”以创建新表。

      1. 在“文件名”框中,输入另一个数据库的位置和文件名。

        单击“浏览”,使用新的“生成表”对话框来定位其他数据库,然后单击“确定”。

      2. 单击“确定”关闭第一个“生成表”对话框。

      3. 单击 " , 然后单击" "以确认操作。

        注意: 如果要替换现有表,则 Access 将首先删除该表并要求您确认删除。 单击“”,然后再次单击“”以创建新表。

了解有关查询条件和表达式的详细信息

本文中的步骤涉及到查询条件和表达式。 查询条件是一条规则,用于标识要包含在查询中的记录;希望给定数据集中仅显示部分记录时,请使用条件。 例如,条件 >25 AND <50 将返回大于 25 且小于 50 的值。 条件 "芝加哥" OR "巴黎" OR "莫斯科" 将仅返回这些城市的记录。

有关使用条件的详细信息,请参阅一文。

表达式结合了数学或逻辑运算符、常量、函数、字段名称、控件以及计算结果为单个值的属性。 需要使用表中不直接包含的数据时,请使用表达式。 例如,表达式 [单价]*[数量] 会将单价字段的值和数量字段的值相乘。 使用表达式的方式多种多样,创建和使用表达式的过程可能非常复杂。

有关创建和使用表达式的详细信息,请参阅一文。

默认情况下,如果打开未保存在可信位置的数据库,或未选择信任该数据库,Access 将阻止运行所有动作查询(追加、更新、删除或生成表查询)。

如果尝试运行某动作查询,但貌似无响应,请查看 Access 状态栏中是否显示下列消息:

“此操作或事件已被禁用模式阻止。”

看到该消息时,请执行下列操作:

  • 在消息栏(位于功能区下方)上单击“启用内容”。

Hive 是建立在 Hadoop 上的数据仓库基础构架。它提供了一系列的工具,可以用来进行数据提取转化加载(ETL),这是一种可以存储、查询和分析存储在 Hadoop 中的大规模数据的机制。Hive 定义了简单的类 SQL 查询语言,称为 QL,它允许熟悉 SQL 的用户查询数据。同时,这个语言也允许熟悉 MapReduce 开发者的开发自定义的 mapper

Hive 的结构可以分为以下几部分:

  • 解释器、编译器、优化器、执行器 

  1. Hive 将元数据存储在数据库中,如 mysql、derby。Hive 中的元数据包括表的名字,表的列和分区及其属性,表的属性(是否为外部表等),表的数据所在目录等。 

  2. 解释器、编译器、优化器完成 HQL 查询语句从词法分析、语法分析、编译、优化以及查询计划的生成。生成的查询计划存储在 HDFS 中,并在随后有 MapReduce 调用执行。 

  • HQL 中对查询语句的解释、优化、生成查询计划是由 Hive 完成的 

2、HIVE的数据存储

    首先,Hive 没有专门的数据存储格式,也没有为数据建立索引,用户可以非常自由的组织 Hive 中的表,只需要在创建表的时候告诉 Hive 数据中的列分隔符和行分隔符,Hive 就可以解析数据。

  1. 指定的数据仓库的目录,所有的 Table 数据(不包括 External Table)都保存在这个目录中。 

  2. External Table 指向已经在 HDFS 中存在的数据,可以创建 Partition。它和 Table 在元数据的组织上是相同的,而实际数据的存储则有较大的差异。 

  • Table 的创建过程和数据加载过程(这两个过程可以在同一个语句中完成),在加载数据的过程中,实际数据会被移动到数据仓库目录中;之后对数据对访问将会直接在数据仓库目录中完成。删除表时,表中的数据和元数据将会被同时删除。 

 它与关系型数据库的SQL 略有不同,但支持了绝大多数的语句如DDL、DML 以及常见的聚合函数、连接查询、条件查询。HIVE不适合用于联机(online)事务处理,也不提供实时查询功能。它最适合应用在基于大量不可变数据的批处理作业。

 HIVE的特点:可伸缩(在Hadoop的集群上动态的添加设备),可扩展,容错,输入格式的松散耦合。

  • CREATE TABLE 创建一个指定名字的表。如果相同名字的表已经存在,则抛出异常;用户可以用 IF NOT EXIST 选项来忽略这个异常

  • EXTERNAL 关键字可以让用户创建一个外部表,在建表的同时指定一个指向实际数据的路径(LOCATION)

  • LIKE 允许用户复制现有的表结构,但是不复制数据

  • COMMENT可以为表与字段增加描述

  用户在建表的时候可以自定义 SerDe 或者使用自带的 SerDe。如果没有指定 ROW FORMAT 或者 ROW FORMAT DELIMITED,将会使用自带的 SerDe。在建表的时候,用户还需要为表指定列,用户在指定表的列的同时也会指定自定义的 SerDe,Hive 通过 SerDe 确定表的具体的列的数据。

创建表并创建索引字段ds

导入数据表的数据格式是:字段之间是tab键分割,行之间是断行。

及要我们的文件内容格式:

按正条件(正则表达式)显示表,

修改列的名字、类型、位置、注释

添加一列并增加列字段注释

修改列的名字、类型、位置、注释:

这个命令可以允许改变列名、数据类型、注释、列位置或者它们的任意组合

添加一列并增加列字段注释

 ADD是代表新增一字段,字段位置在所有列后面(partition列前)

用户可以用这个命令向表中增加metadata

这个命令修改了表的物理存储属性

如果没有提供表名,视图列的名字将由定义的SELECT表达式自动生成

如果修改基本表的属性,视图中不会体现,无效查询将会失败

hive不支持用insert语句一条一条的进行插入操作,也不支持update操作。数据是以load的方式加载到建立好的表中。数据一旦导入就不可以修改。

将查询结果插入到Hive表中

Load 操作只是单纯的复制/移动操作,将数据文件移动到 Hive 表对应的位置。

加载本地数据,同时给定分区信息

加载的目标可以是一个表或者分区。如果表包含分区,必须指定每一个分区的分区名

filepath 可以引用一个文件(这种情况下,Hive 会将文件移动到表所对应的目录中)或者是一个目录(在这种情况下,Hive 会将目录中的所有文件移动至表所对应的目录中)

指定了LOCAL,即本地

load 命令会去查找本地文件系统中的 filepath。如果发现是相对路径,则路径会被解释为相对于当前用户的当前路径。用户也可以为本地文件指定一个完整的 URI,比如:file:///user/hive/project/data1.

load 命令会将 filepath 中的文件复制到目标文件系统中。目标文件系统由表的位置属性决定。被复制的数据文件移动到表的数据对应的位置

例如:加载本地数据,同时给定分区信息:

加载DFS数据 ,同时给定分区信息:

目标表(或者分区)中的内容(如果有)会被删除,然后再将 filepath 指向的文件/目录中的内容添加到表/分区中。

如果目标表(分区)已经有一个文件,并且文件名和 filepath 中的文件名冲突,那么现有的文件会被新文件所替代。

将查询结果插入Hive表

将查询结果插入Hive表

将查询结果写入HDFS文件系统

将查询结果写入HDFS文件系统

数据写入文件系统时进行文本序列化,且每列用^A 来区分,\n换行

使用ALL和DISTINCT选项区分对重复记录的处理。默认是ALL,表示查询所有记录。DISTINCT表示去掉重复的记录

Limit 可以限制查询的记录数

下面的查询语句查询销售记录最大的 5 个销售代表。

SELECT 语句可以使用正则表达式做列选择,下面的语句查询除了 ds 和 hr 之外的所有列:

将查询数据输出至目录:

将查询结果输出至本地目录:

选择所有列到本地目录 :

将一个表的统计结果插入另一个表中:

将多表数据插入到同一表中:

将文件流直接插入文件:

Hive 当前的实现是,只有分区断言出现在离 FROM 子句最近的那个WHERE 子句中,才会启用分区剪枝

join 时,每次 map/reduce 任务的逻辑是这样的:reducer 会缓存 join 序列中除了最后一个表的所有表的记录,再通过最后一个表将结果序列化到文件系统

实践中,应该把最大的那个表写在最后

join 查询时,需要注意几个关键点

如果你想限制 join 的输出,应该在 WHERE 子句中写过滤条件——或是在 join 子句中写

容易混淆的问题是表分区的情况

如果 d 表中找不到对应 c 表的记录,d 表的所有列都会列出 NULL,包括 ds 列。也就是说,join 会过滤 d 表中不能找到匹配 c 表 join key 的所有记录。这样的话,LEFT OUTER 就使得查询结果与 WHERE 子句无关

LEFT SEMI JOIN 的限制是, JOIN 子句中右边的表只能在 ON 子句中设置过滤条件,在 WHERE 子句、SELECT 子句或其他地方过滤都不行

用来合并多个select的查询结果,需要保证select中字段须一致

SQL中对两表内联可以写成:

分号是SQL语句结束标记,在HiveQL中也是,但是在HiveQL中,对分号的识别没有那么智慧,例如:

但HiveQL在解析语句时提示:

解决的办法是,使用分号的八进制的ASCII码进行转义,那么上述语句应写成:

4、Hive不支持将数据插入现有的表或分区中,

仅支持覆盖重写整个表,示例如下:

5、hive支持嵌入mapreduce程序,来处理复杂的逻辑

并且map程序、reduce程序可以单独使用,如:

6、hive支持将转换后的数据直接写入不同的表,还能写入分区、hdfs和本地目录。

这样能免除多次扫描输入表的开销。

现在做一些复杂的数据分析:

我要回帖

更多关于 数据库生成实体类 的文章

 

随机推荐