मेरे पास निम्न प्रश्न है। विचार यह है कि यह मुझे यह जानने की अनुमति देता है कि groups
, और बाद में users
, प्रत्येक component_instance
तक पहुंच है। अगर वहाँ प्रश्न के रूप में यह करने के लिए एक बेहतर तरीका है काफी धीमी है मैं सोच रहा हूँ, लेकिन यह इन अतिरिक्त कॉलम हर बार जब मैं इस तालिका से निपटने के लिए वास्तव में आसान है:एक GROUP_CONCAT क्वेरी को और अधिक कुशल बनाना
SELECT component_instances.*,
GROUP_CONCAT(DISTINCT IF(permissions.view, groups.id, NULL)) AS view_group_ids,
GROUP_CONCAT(DISTINCT IF(permissions.edit, groups.id, NULL)) AS edit_group_ids,
GROUP_CONCAT(DISTINCT IF(permissions.view, users.id, NULL)) AS view_user_ids,
GROUP_CONCAT(DISTINCT IF(permissions.edit, users.id, NULL)) AS edit_user_ids
FROM `component_instances`
LEFT OUTER JOIN permissions ON permissions.component_instance_id = component_instances.id
LEFT OUTER JOIN groups ON groups.id = permissions.group_id
LEFT OUTER JOIN groups_users ON groups_users.group_id = groups.id
LEFT OUTER JOIN users ON users.id = groups_users.user_id
GROUP BY component_instances.id
ORDER BY (case when component_instances.ancestry is null then 0 else 1 end), component_instances.ancestry, position
अनुमतियाँ तालिका इसलिए की तरह है (रेल बहाना!):
create_table "permissions", :force => true do |t|
t.integer "component_instance_id"
t.integer "group_id"
t.boolean "view", :default => false
t.boolean "edit", :default => false
end
अनुमतियों के प्रकार edit
, और view
हैं। एक समूह को या दोनों को सौंपा जा सकता है। यदि component_instance
पर कोई समूह अनुमति नहीं है, तो अनुमतियां भी पुनरावर्ती हैं, हमें पहले अपने पूर्वजों को जांचना होगा जहां अनुमतियां सेट की गई हैं (यदि कोई हो)। इससे एक प्रश्न बहुत महत्वपूर्ण हो जाता है क्योंकि मैं इस क्वेरी को चयन तर्क के साथ जोड़ सकता हूं कि ancestry
मणि (भौतिक पथ पथ) प्रदान करता है।
अद्यतन
मैंने जब से इस क्वेरी मानक तेजी से मिला:
SELECT component_instances.*,
GROUP_CONCAT(DISTINCT view_groups.id) AS view_group_ids,
GROUP_CONCAT(DISTINCT edit_groups.id) AS edit_group_ids,
GROUP_CONCAT(DISTINCT view_users.id) AS view_user_ids,
GROUP_CONCAT(DISTINCT edit_users.id) AS edit_user_ids
FROM `component_instances`
LEFT OUTER JOIN permissions ON permissions.component_instance_id = component_instances.id
LEFT OUTER JOIN groups view_groups ON view_groups.id = permissions.group_id AND permissions.view = 1
LEFT OUTER JOIN groups edit_groups ON edit_groups.id = permissions.group_id AND permissions.edit = 1
LEFT OUTER JOIN groups_users view_groups_users ON view_groups_users.group_id = view_groups.id
LEFT OUTER JOIN groups_users edit_groups_users ON edit_groups_users.group_id = edit_groups.id
LEFT OUTER JOIN users view_users ON view_users.id = view_groups_users.user_id
LEFT OUTER JOIN users edit_users ON edit_users.id = edit_groups_users.user_id
GROUP BY component_instances.id
ORDER BY (case when component_instances.ancestry is null then 0 else 1 end), component_instances.ancestry, position
यहाँ एक ऊपर क्वेरी के लिए समझाने और तालिका बनाने के बयान है:
+----+-------------+---------------------+--------+-----------------------------------------------+--------------------------------------------+---------+--------------------------------------------+------+------------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------------------+--------+-----------------------------------------------+--------------------------------------------+---------+--------------------------------------------+------+------------------------------------------------------+
| 1 | SIMPLE | component_instances | ALL | PRIMARY,index_component_instances_on_ancestry | NULL | NULL | NULL | 119 | "Using temporary; Using filesort" |
| 1 | SIMPLE | permissions | ALL | NULL | NULL | NULL | NULL | 6 | "Using where; Using join buffer (Block Nested Loop)" |
| 1 | SIMPLE | view_groups | eq_ref | PRIMARY | PRIMARY | 4 | 05707d890df9347c.permissions.group_id | 1 | "Using where; Using index" |
| 1 | SIMPLE | edit_groups | eq_ref | PRIMARY | PRIMARY | 4 | 05707d890df9347c.permissions.group_id | 1 | "Using where; Using index" |
| 1 | SIMPLE | view_groups_users | ref | index_groups_users_on_group_id_and_user_id | index_groups_users_on_group_id_and_user_id | 5 | 05707d890df9347c.view_groups.id | 1 | "Using index" |
| 1 | SIMPLE | edit_groups_users | ref | index_groups_users_on_group_id_and_user_id | index_groups_users_on_group_id_and_user_id | 5 | 05707d890df9347c.edit_groups.id | 1 | "Using index" |
| 1 | SIMPLE | view_users | eq_ref | PRIMARY | PRIMARY | 4 | 05707d890df9347c.view_groups_users.user_id | 1 | "Using index" |
| 1 | SIMPLE | edit_users | eq_ref | PRIMARY | PRIMARY | 4 | 05707d890df9347c.edit_groups_users.user_id | 1 | "Using index" |
+----+-------------+---------------------+--------+-----------------------------------------------+--------------------------------------------+---------+--------------------------------------------+------+------------------------------------------------------+
CREATE TABLE `component_instances` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`visible` int(11) DEFAULT '1',
`instance_id` int(11) DEFAULT NULL,
`deleted_on` date DEFAULT NULL,
`instance_type` varchar(255) DEFAULT NULL,
`component_id` int(11) DEFAULT NULL,
`deleted_root_item` int(11) DEFAULT NULL,
`locked_until` datetime DEFAULT NULL,
`theme_id` int(11) DEFAULT NULL,
`position` int(11) DEFAULT NULL,
`ancestry` varchar(255) DEFAULT NULL,
`ancestry_depth` int(11) DEFAULT '0',
`cached_name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `index_component_instances_on_ancestry` (`ancestry`)
) ENGINE=InnoDB AUTO_INCREMENT=121 DEFAULT CHARSET=utf8
CREATE TABLE `groups` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
CREATE TABLE `groups_users` (
`group_id` int(11) DEFAULT NULL,
`user_id` int(11) DEFAULT NULL,
KEY `index_groups_users_on_group_id_and_user_id` (`group_id`,`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
CREATE TABLE `permissions` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`component_instance_id` int(11) DEFAULT NULL,
`group_id` int(11) DEFAULT NULL,
`view` tinyint(1) DEFAULT '0',
`edit` tinyint(1) DEFAULT '0',
PRIMARY KEY (`id`),
KEY `edit_permissions_index` (`edit`,`group_id`,`component_instance_id`),
KEY `view_permissions_index` (`view`,`group_id`,`component_instance_id`)
) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`real_name` varchar(255) DEFAULT NULL,
`username` varchar(255) NOT NULL DEFAULT '',
`email` varchar(255) NOT NULL DEFAULT '',
`crypted_password` varchar(255) DEFAULT NULL,
`administrator` int(11) NOT NULL DEFAULT '0',
`password_salt` varchar(255) DEFAULT NULL,
`remember_token_expires` datetime DEFAULT NULL,
`persistence_token` varchar(255) DEFAULT NULL,
`disabled` tinyint(1) DEFAULT NULL,
`time_zone` varchar(255) DEFAULT NULL,
`login_count` int(11) DEFAULT NULL,
`failed_login_count` int(11) DEFAULT NULL,
`last_request_at` datetime DEFAULT NULL,
`current_login_at` datetime DEFAULT NULL,
`last_login_at` datetime DEFAULT NULL,
`current_login_ip` varchar(255) DEFAULT NULL,
`last_login_ip` varchar(255) DEFAULT NULL,
`perishable_token` varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
UNIQUE KEY `index_users_on_username` (`username`),
KEY `index_users_on_perishable_token` (`perishable_token`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8
ORDER BY
ancestry gem से आता है लेकिन यदि ऐसा करने का एक बेहतर तरीका है तो मुझे submi से प्रसन्नता होगी टी कि उन्हें एक पुल अनुरोध के रूप में।
यह प्रश्न में अपने सभी पाठ रखने मैं एक 'UPDATE' लाइन का उपयोग मेरी प्रत्येक अद्यतन को अलग करने और सभी प्रश्न भाग में स्टेम रखने होगा अगर मैं तुम्हें थे प्रथागत है। यह पढ़ने के लिए और अधिक स्पष्ट बनाता है। – Mehran
धन्यवाद मेहरान, मैंने इसे अपडेट किया है। मैं शुरू में अपने स्वयं के प्रश्न का उत्तर देने गया, फिर एक बक्षीस करने के लिए सोचा। –
यह भी मुझे लगता है कि यदि आप दूसरे संस्करण का उपयोग कर रहे हैं तो आप पिछले दो जोड़ों को छोड़ सकते हैं और group_concat – maraca