美文网首页
数据库高级使用

数据库高级使用

作者: yaya_pangdun | 来源:发表于2016-06-12 14:25 被阅读69次

1、在Model使用sql语句

before_destroy :clean_data

def clean_data
  teacher_id = self.id
  sql = "delete * from train_teacher where nurse_info_id = #{teacher_id}"
  #这个方法是私有方法,必须在Model中使用
  ActiveRecord::Base.connection.exec(sql)
end

2、数据库的优化
一. N+1 queries 问题

# model
class User < ActieRecord::Base
  has_one :car
end

class Car < ActiveRecord::Base
  belongs_to :user
end

# your controller
def index
  @users = User.page(params[:page])
end

# view
<% @users.each do |user| %>
 <%= user.car.name %>
<% end %>

当我们在View中使用user.car.name的时候,会导致N+1 queries(多次查询数据库),假设User有10笔,这程式会产生出11笔Queries,一笔是查
User,另外10笔是一笔一笔去查Car,严重拖慢效能。

SELECT * FROM `users` LIMIT 10 OFFSET 0
SELECT * FROM `cars` WHERE (`cars`.`user_id` = 1)
SELECT * FROM `cars` WHERE (`cars`.`user_id` = 2)
SELECT * FROM `cars` WHERE (`cars`.`user_id` = 3)
...
...
...
SELECT * FROM `cars` WHERE (`cars`.`user_id` = 10)

解决方法,加上includes:

# your controller
def index
  @users = User.includes(:car).page(params[:page])
end

如此SQL query就只有两个,只用一个就查出所有Cars资料。

SELECT * FROM `users` LIMIT 10 OFFSET 0
SELECT * FROM `cars` WHERE (`cars`.`user_id` IN('1','2','3','4','5','6','7','8',' 9','10'))

二. 索引
需要加索引的列:

  • 外键(Foreign Key)
  • 需要排序的列
  • 被查询的列
  • 会被group的列

三. 使用select
ActiveRecord会将数据库中的所有列取出来,浪费内存。

#只取出id,name,description这些字段
Event.select(:id, :name, :description).limit(10)

四. 使用计数器
在ActiveRecord中经常要计算has_many的Model有多少关联的数据。

<% @topics.each do |topic| %>
  主题:<%= topic.subject %>
  回复数:<%= topic.posts.size %>
<% end %>

这个时候会产生很多SQL查询。

SELECT * FROM `posts` LIMIT 5 OFFSET 0
SELECT count(*) AS count_all FROM `posts` WHERE (`posts`.topic_id = 1 )
SELECT count(*) AS count_all FROM `posts` WHERE (`posts`.topic_id = 2 )
SELECT count(*) AS count_all FROM `posts` WHERE (`posts`.topic_id = 3 )
SELECT count(*) AS count_all FROM `posts` WHERE (`posts`.topic_id = 4 )
SELECT count(*) AS count_all FROM `posts` WHERE (`posts`.topic_id = 5 )

使用counter cache会把这个数字存进数据库。必须在Topic这个Model增加一个字段。

rails g migration add_posts_count_to_topic

编辑Migration文件

class AddPostsCountToTopic < ActiveRecord::Migration
  def change  
    add_column :topics, :posts_count, :integer, :default => 0
    
    Topic.pluck(:id).each do |i|
      Topic.reset_counters(i, :posts) # 全部重算一次
    end
  end
end

编辑Model文件,加入counter_cache => true

class Topic < ActiveRecord::Base
  has_many :posts
end

class Posts < ActiveRecord::Base
  belongs_to :topic, :counter_cache => true
end

这样topic.posts.size会自动转化为topic.posts_count
五. 查询优化
如果要查出所有的数据,不要用all,all会一次把所有的数据取到内存中去。


六. 逆正规化

相关文章

  • 数据库知识点

    数据库知识点 数据库相关概念 mysql安装与使用 navicat的使用 SQL语言的查询(重点) 高级(了解) ...

  • Models and Databases 4.search

    文本查询 使用contains icontains 数据库高级比较方式 使用PGSQL 基于文档的查询 全文搜索:...

  • 数据库高级使用

    1、在Model使用sql语句 2、数据库的优化一. N+1 queries 问题 当我们在View中使用us...

  • 数据库基础Database3-高级SQL

    数据库基础Database3 四 高级SQL 4.1 使用程序设计语言访问数据库 JDBC 4.2 函数和过程 (...

  • SQL高级

    高级sql语句 1.select top limit rownum (不同数据库使用不同的) 2.SELE...

  • mysql学习日记(1)

    为什么要学数据库? 因为要更加高效的存储和使用数据,所以必须要学会使用数据库,当然这也分为简单的增删改查以以及高级...

  • 数据分析学习路线

    业务数据分析师 1. Excel必备工具使用和高级技巧 2. Mysql数据库 3. SPSS Modeler数据...

  • mysql高级知识

    mysql高级知识系列目录 存储过程与函数 理解MySQL数据库覆盖索引 为什么 MySQL 索引要使用 B+树而...

  • 数据库相关资料

    CMU 数据库高级教程CMU 数据库初级教程 LLVM 资料汇总

  • mybatis的mapper特殊字符转移以及动态SQL条件查询

    前言 我们知道在项目开发中之前使用数据库查询,都是基于jdbc,进行连接查询,然后是高级一点jdbcTemplat...

网友评论

      本文标题:数据库高级使用

      本文链接:https://www.haomeiwen.com/subject/gwvedttx.html