Optimización y Desnormalización del Modelo de Datos. Fernando Blat fernando.blat@the-cocktail.com http://www.inwebwetrust.net



Documentos relacionados
Gastón Ramos - ramos.gaston@gmail.com

- Bases de Datos - - Diseño Físico - Luis D. García

Sesión 20. MVC en ruby on rails. Luisa Fernanda Rincón Pérez

UNIVERSIDAD DEL ISTMO CAMPUS IXTEPEC LIC. INFORMATICA GRUPO 508 PROCEDIMIENTOS ALMACENADOS EN SQL SERVER 2000

CONSULTAS CON SQL. 3. Hacer clic sobre el botón Nuevo de la ventana de la base de datos. Aparecerá el siguiente cuadro de diálogo.

Guía de utilización del plugin para WordPress All in One SEO Pack

BASE DE DATOS QUÉ ES UNA BASE DE DATOS?

PHP Perfect SQL v1.0 (SQL perfectas en PHP)

Optimizar base de datos WordPress

Bases de datos. 1. Introducción

2.4 Modelado conceptual

Guía de implementación Softland en SQL Server Versión 1.0

PHP y MySQL. Inicio: - Herencia - Palabra clave Final - Polimorfismo - Type Hinting - Abstracción de clases

CAPÍTULO 3 Servidor de Modelo de Usuario

Bases de Datos Relacionales

Lenguaje Ruby y su entorno

Tema 1: Introducción

Diseño de bases de datos Diapositiva 1

Hacer obligatorio tener persona de contacto.

Ahora por tan solo Euros/mes 50% de descuento, Sin ataduras!!

5.4. Manual de usuario

INTRODUCCIÓN A PHP. Javier Enciso

Introducción CAPÍTULO 1

UNIDAD 2: Abstracción del Mundo real Al Paradigma Orientado a Objetos

proceso que consiste en aplicar una serie de reglas a las relaciones obtenidas tras el paso del modelo entidad-relación al modelo relacional.

Cybersudoe Innov: Una red de expertos sobre TIC e Innovación del SUDOESTE europeo

Propiedad Colectiva del Código y Estándares de Codificación.

select nombre from profesores where categoria='aso6';

1.264 Tema 7. Introducción a SQL

APLICACIÓN PRÁCTICA EN ESPAÑA DE LA NORMATIVA "SEPA" EN PROGRAMAS MDG

Anunciantes: consejos para la integración de los tags Reactivpub en Joomla

Gestión de Cambios de BDD con LiquiBase. ISC Abril 2012 Paulo Clavijo Esteban

Gestión de Requisitos ULPGC

Presentación de servicios

Curso de Java POO: Programación orientada a objetos

Estas visiones de la información, denominadas vistas, se pueden identificar de varias formas.

Cómo integrar el Control Presupuestario en el Reporting

Brother PE-design Plus.

1

Repaso de Conceptos Básicos de Bases de Datos

Enlace a la web:

Iniciando con Oracle. Índice de contenido. Ingresando a Oracle. Cambiando Su Contraseña. Ingresando un Comando SQL en SQL*Plus

Elementos requeridos para crearlos (ejemplo: el compilador)

Aplicaciones de las vistas Concepto de vista Vistas en SQL Vistas en SQL.

Consultas con combinaciones

SAQQARA. Correlación avanzada y seguridad colaborativa_

ARQUITECTURA DE DISTRIBUCIÓN DE DATOS

Programación en Internet Curso Índice

Ruby on Rails con Hobo. Cursos eghost Julio 2011 Ibon Castilla e Ignacio Huerta UnoyCero.com

Capítulo IV. Implementación del Sistema

Tutorial de Unity 3D Tema 52 Bases de Datos. Tutorial de Unity 3D. Bases de Datos

Capitulo VI. Conclusiones.

BASE DE DATOS: ENFOQUE ORIENTADO A OBJETOS. Dámaso López Aragón

Creación y administración de grupos de dominio

Hostaliawhitepapers. Las ventajas de los Servidores dedicados. Cardenal Gardoki, BILBAO (Vizcaya) Teléfono:

Práctica 3. Consultas SQL

Unidad III: Lenguaje de manipulación de datos (DML) 3.1 Inserción, eliminación y modificación de registros

Introducción Delicious Algunas características: Sitio para acceder a esta herramienta Qué es Delicious?...

Temario. Introducción Hello Word y Literales Expresiones Bloques Programación orientada a objetos (OOP) Introspección Rake Gemas

ESPECIFICACIÓN DE VIDEOCLUB

Sql Basico. Seminar Introduction

Puedes descargar los archivos de instalación de Windows SteadyState en el Centro de descarga Microsoft.

ERP Una inversión que rendirá frutos. FASCÍCULO

8972 Personalización y Configuración de Microsoft Dynamics CRM 4.0

LAS SUBCONSULTAS SQL SERVER Manual de Referencia para usuarios. Salomón Ccance CCANCE WEBSITE

Pruebas de unidad con JUnit

XIII Jornadas de Enseñanza Universitaria de la Informática Teruel, 2007

Bases de datos: Sistemas de bases de datos:

Trabajando con atributos y dominios

GESTOR DE REFERENCIAS EndNote Web

Introducción a Protégé

1. DML. Las subconsultas

Gestor de Contenidos CMS. Prof: Ing. Henrry Servitá

MANUAL WEBSOPORTE DE IRIS-EKAMAT

Planificamos y escribimos avisos publicitarios para nuestra revista

Gestión de Procesos de Compra. Documentación Técnico Comercial

Cómo aprovechar mejor el Webinar

Integración de Magento & Dynamics NAV

Guía E-Cupones: Inicio

PROCESOS DE RAZONAMIENTO INVERSO: PATRÓN DE DISEÑO ADAPTER EN PYTHON Y PHP, LOS

Ciclo de vida y Metodologías para el desarrollo de SW Definición de la metodología

Tema 4. Manipulación de datos con SQL

TUTORIAL DIDÁCTICO Material recomendado. PICASA Crear un álbum de fotos compartido

Patrones para persistencia (I) Ingeniería del Software II

Aviso Legal El presente libro electrónico se distribuye bajo Attribution-NonCommercial- NoDerivs 3.0 Unported

SGIC. Propuesta para Plan de Telefonía y Perfiles de Consumo

Capítulo 3 Usando GUIDE. 3.1 Acerca de GUIDE

openfwpa Internacional Módulo SMS (MSMS)

Sistemas de Información 12/13 La organización de datos e información

Mantenimiento Limpieza

Gong-R - Soporte #54 Problemas en Gong

Esta extensión está obsoleta a partir de PHP 5.5.0, y será eliminada en el futuro

Lista de implementación de GoogleAnalytics

WPeMatico. Wordpress-Plugin

1. Que es un nombre de dominio? Es un conjunto de caracteres alfanuméricos utilizados para identificar una computadora determinada en Internet.

Pierre ALAUZET Ludovic JEANSON Chama EL-HASSOUNI Agnés LEBON Proyecto Practico de Construcción de un Software

Primeramente estudiaremos la forma básica de la sentencia SELECT, que esta formado por:

DML SQL II. Comparaciones con relaciones

Microsoft Access proporciona dos métodos para crear una Base de datos.

Laboratorio 7 Motor de búsqueda web basado en el TAD Árbol Binario de Búsqueda GUIÓN DEL LABORATORIO

Transcripción:

Optimización y Desnormalización del Modelo de Datos Fernando Blat fernando.blat@the-cocktail.com http://www.inwebwetrust.net 1

Índice Índice Qué es ActiveRecord? Modelo de datos de ejemplo Normalización / Desnormalización del modelo Tags en La Coctelera Observers Conclusiones 2

3 Introducción a ActiveRecord

Introducción a ActiveRecord Qué es ActiveRecord? Librería de Rails encargada de mapear los objetos de negocio en las la base de datos Crear un sistema de clases que podemos utilizar en nuestra aplicación Implementa el patrón Object Relational Mapping (ORM) Lo extiende proponiendo dos nuevos conceptos: relaciones y herencia 4

Introducción a ActiveRecord Filosofía Olvida la base de datos Toda la magia de Ruby para trabajar con el modelo de datos Minimizar el número de líneas y maximizar la productividad Independiente de Rails 5

Introducción a ActiveRecord Qué se puede hacer? Post.find(:all, :conditions => "status='publish') # SELECT * from posts WHERE status='publish' Post.find_by_nicetitle('como optimizar active record') # SELECT * from posts WHERE nicetitle='como optimizar active record' LIMIT 1 post.categories # SELECT * from categories WHERE post_id='3' post.author # SELECT * from people WHERE id='10' 6

Introducción a ActiveRecord Características Mapeo automático entre clases y tablas: tabla posts corresponde a la clase Post Asociacies entre clases Validación de atributos acts_as_(list tree) Callbacks Observers Herencia Transacciones Manipulación directa de objetos Abstracción de la base datos Soporte para logging 7

Introducción a ActiveRecord Usando AR fuera de Rails require 'rubygems' requiregem 'activerecord' ActiveRecord::Base.establish_connection({ :adapter => "sqlite3", :dbfile => "db/db.posts.sqlite3" }) class Post < ActiveRecord::Base set_table_name 'posts' end posts = Post.find_all_by_date('2006 11 25') 8

9 Nuestro pequeño modelo de datos

Nuestro pequeño modelo de datos Categoría class Category < ActiveRecord::Base has_many :posts end Persona class Person < ActiveRecord::Base has_many :posts end 10

Nuestro pequeño modelo de datos Post class Post < ActiveRecord::Base has_many :categories belongs_to :author, :class_name => 'Person' end validates_presence_of :title validates_presence_of :body 11

Nuestro pequeño modelo de datos Y en la base de datos... create_table "posts" do t... t.column "user_id", :integer... end create_table "posts_categories", :id => false do t t.column "post_id", :integer t.column "category_id", :integer end create_table "categories" do t... end 12

13 (des) normalización

El modelo de datos normalizado La Normalización... no es un capricho impide la duplicación de los datos evita la inconsistencia organiza las tablas y los datos de forma más natural produce esquemas más fáciles de entender 14

El modelo de datos normalizado Así que si no normalizas... ten cuidado con la inconsistencia modificar un mismo valor implica actualizar varios campos aumentan las posibilidades de cometer errores 15

El modelo de datos normalizado category.posts SELECT * FROM posts INNER JOIN posts_categories ON posts.id = posts_categories.post_id WHERE (posts_categories.category_id = 41609) ORDER BY date DESC; # 0.135517 segs. 16

El modelo de datos normalizado No es para tanto en este caso, y posiblemente muchos otros, no es para tanto tener que trabajar con un modelo normalizado hay pocos datos: número pequeño de categorías, y de posts en dichas categorías siempre se trabaja en el dominio del usuario 17

18 Mamá, quiero tags

acts_as_taggable acts_as_taggable plugin desarrollado por DHH polimórfico introduce dos modelos: Tag y Tagging Tag contiene el identificador y el nombre Tagging contiene la relación con otros modelos 19

acts_as_taggable Tag class Tag < ActiveRecord::Base has_many :taggings validates_uniqueness_of :name Tagging class Tagging < ActiveRecord::Base belongs_to :tag belongs_to :taggable, :polymorphic => true belongs_to :user 20

acts_as_taggable El plugin permite... user.tags post.tags post.tag_with( css stylshet css4 w3c ) Post.find_tagged_with( rails ) 21

Qué hacer con los tags? Nubes de tags el primer día +4.000 tags diferentes ahora +40.000 tags diferentes +100.000 posts taggeados 22

Qué hacer con los tags? Sugerir tags hay usuarios con +1.000 tags 23

Qué hacer con los tags? Implementando una nube de tags: ActiveRecord way: tags = Tag.find(:all).sort do a,b a.taggings.size <=> b.taggings.size end tags = tags[0...150] Tantos SELECT como tags tengamos 24

Qué hacer con los tags? Implementando una nube de tags: Optimizando con SQL: select *,count(tag_id) as c from taggings group by tag_id order by c desc limit 150; 150 SELECT + 1 25

26 Qué hacer?

acts_as_taggable Cachear! No, si se está regenerando continuamente No, si, por muy poco que regeneremos la caché se genera una consulta de cientos de Mb que satura la máquina No es una solución a largo plazo 27

28 Entonces?

acts_as_taggable Desnormalizamos el modelo Combinamos en una tabla, atributos de varias Introducimos los campos calculados... 29

acts_as_taggable Objetivo Reducir al mínimo el número de SELECT Poder utilizar el LIMIT Si has de ordenar, que sea a través de la BBDD Reducir al mínimo el número de atributos replicados Mantener la consistencia a base de reglas y callbacks Tratar cada situación de forma especial 30

acts_as_taggable temporal_tags create_table "temporal_tags" do t t.column "name", :string t.column "count", :integer end temporal_user_tags create_table "temporal_user_tags" do t t.column "tag_id", :integer t.column "user_id", :integer t.column "username", :string t.column "name", :string t.column "count", :integer end 31

Mantenemos los modelos existentes y añadimos tablas, que no modelos, con los datos desnormalizados 32

Cómo mantener todo este caos a raya? 33

Observers observers Un observer responde eventos sobre un objeto Se integra perfectamente con el modelo config/environment.rb: config.active_record.observers = :comment_observer app/controllers/application.rb: observer :comment_observer class CommentObserver < ActiveRecord::Observer def after_save(comment) Notifier.deliver_comment("admin@lacoctelera.com", "Hay un nuevo comentario", comment) end end 34

Callbacks observers before_validation before_validation_on_create after_validation after_validation_on_create before_save before_create after_create after_save 35

Funcionamiento observer Creamos un tagging_observer Definimos una acción para el callbak after_save Se actualizan las tablas desnormalizadas globales, diarias y de usuario class TTag < ActiveRecord::Base set_table_name "temporal_tags" end class TDTag < ActiveRecord::Base set_table_name 'temporal_daily_tags' end 36

tagging_observer.rb observer class TaggingObserver < ActiveRecord::Observer def after_save(tag) begin #actualización t = TTag.find(tag.tag_id) t.update_attribute(:count, t.count+1) rescue # creación t = TTag.new t.id = tag.tag_id t.name = tag.name thetag = Tag.find_by_sql("select tags.id as id, tags.name as name, count(tag_id) as count from taggings, tags where taggings.taggable_type = '#{tag.taggable_type}' and taggings.tag_id = tags.id and tags.id = '#{tag.tag_id}' group by tag_id limit 1").first t.count = (thetag)? thetag.count : 1 t.save end end end 37

tagging_observer.rb observer class TaggingObserver < ActiveRecord::Observer def after_save(tag) begin #actualización t = TTag.find(tag.tag_id) t.update_attribute(:count, t.count+1) rescue # creación... end end end 38

observer 39 tagging_observer.rb... rescue # creación t = TTag.new t.id = tag.tag_id t.name = tag.name thetag = Tag.find_by_sql("select tags.id as id, tags.name as name, count(tag_id) as count from taggings, tags where taggings.taggable_type='#{tag.taggable_type}' and taggings.tag_id = tags.id and tags.id = '#{tag.tag_id}' group by tag_id limit 1").first t.count = (thetag)? thetag.count : 1 t.save end end end

observers Funcionamiento Repetiríamos el mismo método para el resto de tablas de tags script de carga inicial de los datos MySQL: Engine=Memory Tests 40

41 Tests

observer Tests: antes def test_post_create_with_tags cine_before = TTag.find_by_name('citas') assert cine_before.count, 2 terror_before = TTag.find_by_name('frases') assert_nil terror_before 42

observer Tests: durante get :new,{},{'user' => User.find(1000) } assert_response :success post :create, {"publish"=>"publicado", "post"=>{"body"=>"cuerpo sano en mente sana", "title"=>"toma yogur y haz sudokus", "id"=>"", "user_id"=>"1000"}, "tag" => { "name" => "citas frases"} }, {'user' => User.find(1000) } assert_response :redirect 43

observer Tests: después cine_after = Ttag.find_by_name('citas') assert cine_after.count, 3 terror_after = Ttag.find_by_name('frases') assert_not_nil terror_after assert terror_after.count, 1 44

observers Tests Testear todos los modelos desnormalizados Testear todos los callbacks que utilicemos Testear cada posibilidad dentro de cada callback No tiene porqué haber inconsistencia en los datos 45

46 Conclusiones

Conclusiones Ten cuidado con ActiveRecord y conoce a fondo en qué consultas se traduce Analiza logs y estudia comportamientos anormales: dispatch de cienes de megas, demasiadas consultas por petición, etcétera Vale la pena empezar directamente con un modelo desnormalizado? Si tienes cuidado no tiene porqué llegar a darse una situación de inconsistencia Testea lo que haces 47

48 Preguntas?

Salamanca 17 Madrid 28020 España tel. +34 91 567 0605 www.the-cocktail.com 49